滑动窗口(4)_将x减到0的最小操作数

news2024/11/24 7:19:53

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

滑动窗口(4)_将x减到0的最小操作数

收录于专栏【经典算法练习
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 题目链接:

2. 题目描述 :

3. 解法 :

    解法一(暴力枚举) :

    算法思路 :

    具体步骤 :

    代码展示 :

    结果分析 :

    对暴力算法的反思与优化

    解法二(滑动窗口) :

    算法思路 :

    图解流程 :

    代码展示 :

    结果分析 :


1. 题目链接:

OJ链接:将x减到0的最小操作数

2. 题目描述 :

给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。

如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。

示例 1:

输入:nums = [1,1,4,2,3], x = 5
输出:2
解释:最佳解决方案是移除后两个元素,将 x 减到 0 。

示例 2:

输入:nums = [5,6,7,8,9], x = 4
输出:-1

示例 3:

输入:nums = [3,2,20,1,1,3], x = 10
输出:5
解释:最佳解决方案是移除后三个元素和前两个元素(总共 5 次操作),将 x 减到 0 。

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 104
  • 1 <= x <= 109

3. 解法 :

    解法一(暴力枚举) :

    算法思路 :

我们可以发现这道题如果说按照题目的意思来写将会变得非常困难!x依次从开始和结尾取数相减,直到x等于0.那具体取了几个开头元素几个结尾元素我们不得而知,所以这里我们需要对题目进行转化: 找出最长的子数组的长度(len),所有元素的和正好等于 sum - x(这里的sum就是整个数组的和),我们最后的结果就是n-len
通过我们这样一转化,我们就可以使用暴力枚举,找出最长子数组的长度!

    具体步骤 :

  1. 用两层循环遍历整个数组
  2. 用tmp记录两个指针区域见的总和
  3. 让右边的指针一直++,直到tmp >= target(sum - x),后面就不需要再遍历了,因为数组中的数>=1
  4. 如果此时tmp == target,记录下此时的最长子数组的长度
  5. i++,j=i.重复上述步骤

    代码展示 :

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int sum = 0;
        for(auto s : nums) sum += s;
        int n = nums.size(), ret = -1, target = sum - x;
        //x == sum 的情况
        if(target == 0) return n;
        //小优化
        if(target < 1 && target != 0) return ret;
        for(int i = 0; i < n; i++)
        {
            int tmp = 0;
            for(int j = i; j < n; j++)
            {
                tmp += nums[j];
                if(tmp == target) ret = max(ret, j - i + 1);
                if(tmp > target) break;

            }
        }
        if(ret == -1) return ret;
        else return n - ret;
    }
};

    结果分析 :

老样子分析一下题目所给的范围:

题目vector数组中数的范围是在[0, 10^5]之内,而我们暴力算法的时间复杂度为O(N^2),总的数据级别超过10^10,这样系统会判定超时!!!

    对暴力算法的反思与优化

10个暴力算法9个通过不了,但是暴力算法能给我们带来一些优化的思路:

就比如我们这道题,当我们暴力算法遍历到下面这种情况时:i++,j = i再重新继续遍历数组

我们就可以发现j其实不需要动,因为i++后,我们的tmp肯定减小,如果i++后,tmp还是大于target的话,我们只需让i一直++即可,因为就算让j重新等于i,那么同样会在j之前的位置大于target,我们这里就使用了滑动窗口让i,j之间的数永远小于target,这是一个动态维护的区间.

 

    解法二(滑动窗口) :

    算法思路 :

题目要求的是数组[左端 + 右端]两段连续的,和为x的最短数组,信息量稍微多一些,不易清理思路;我们就可以转化成求数组内一段连续的,和为sum(nums - x) 的最长数组(和暴力算法一样).此时,就是熟悉的[滑动窗口]问题了

    图解流程 :

1.转化问题: 求target = sum(nums) - x.如果target < 0,问题无解

2.初始化左右指针left = 0, right = 0(滑动窗口区间表示为(left, right),左右区间是否

开闭很重要,必须设定与代码一致),记录当前滑动窗口内数组和的变量sum = 0,

记录当前满足条件数组的最大区间长度ret = -1

3. 当right小于等于数组长度时, 一直循环:
        a. 如果sum < target, 右移右指针, 直至变量和大于等于target, 或右指针已经移到头
        b. 如果sum > target, 右移左指针, 直至变量和小于等于target, 或左指针已经移到头
        c. 如果经过前两步的左右移动使得sum == target, 维护满足条件数组的最大长度, 并

让下一个元素进入窗口

 

 

 

 

    代码展示 :

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int n = nums.size(), left = 0, right = 0, ret = -1;
        int sum = 0, tmp = 0;
        for(auto s : nums) sum += s;
        int target = sum - x;
        if(target < 0) return -1;
        while(right < n)
        {
            tmp += nums[right];
            if(tmp > target) 
                while(tmp > target) tmp -= nums[left++];
            if(tmp == target) ret = max(ret, right - left + 1);
            right++;
        }
        if(ret == -1) return ret;
        else return n - ret;
    }
};

 

    结果分析 :

时间复杂度: O(N)

空间复杂度: O(1)

滑动窗口在这道题中是一种效率很高的解决方法.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2135476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CANFD在乘用车应用说明

随着汽车电子的高速发展&#xff0c;车内信息的急剧增多&#xff0c;传统的CAN总线的数据传输能力已经很难满足车辆ECU的数据传输需求了&#xff0c;此时CANFD就应运而生了。CANFD和CAN最主要的区别就是CANFD的ID段和数据段能够以不同的速率传输数据&#xff0c;这就保证了即使…

【Python】生成图片验证码

1. 首先安装第三方库PIL&#xff08;图像处理库&#xff09; pip install pillow 2. 编写生成验证码代码 这里字体 SimHei.ttf 文件要放在该文件目录下。 import random from PIL import Image, ImageDraw, ImageFont, ImageFilterdef check_code(width128, height30, char…

UE-- 引入IOS framework 库 真机运行闪退

UE-- 引入IOS framework 库 真机运行闪退 事请是这样的 我编写了一个插件 里面是 调用IOS原生代码的 obj-c与swift混编 我从Xcode编写了一个framework库&#xff08;动态库&#xff09; 然后放入ue进行引用 正常的打包出来了 ipa 文件 结果真机运行报错了 Exception Typ…

Apache SeaTunnel Committer 进阶指南

Apache SeaTunnel 作为一个开源的数据集成工具&#xff0c;旨在简化和加速海量数据的采集和传输。 社区的 Committer 是指拥有项目存储库的写权限的社区成员&#xff0c;即 Committer 可以自行修改代码、文档和网站&#xff0c;也可以合并其他成员的贡献。成为 Apache SeaTunn…

eHR软件好用吗?人事管理系统的功能有哪些?

随着科技的发展&#xff0c;企业管理方式也在不断变革。其中&#xff0c;电子人力资源管理&#xff08;eHR&#xff09;系统作为一种新兴的人力资源管理工具&#xff0c;受到了越来越多企业的关注。那么&#xff0c;eHR系统到底好不好用&#xff1f;它有哪些具体功能呢&#xf…

解决Docker镜像不可下载

使用国内可信的镜像中心 可信国内镜像网址&#xff1a;https://hub.atomgit.com/ 点击镜像仓库 搜索想要的镜像 按如图所示&#xff0c;即可查看对应的版本 点击复制&#xff0c;即可下载使用 缺点&#xff1a; 可用的镜像相比于docker官方量少 并且&#xff0c;获取的镜像名字…

架构师知识梳理(七):软件工程-测试

测试原则和方法 系统测试是为了发现错误而执行程序的过程&#xff0c;成功的测试是发现了至今尚未发现的错误的测试。 测试原则 应尽早并不断的进行测试&#xff1b;测试工作应该避免由原开发软件的人或小组承担&#xff1b;在设计测试方案时&#xff0c;不仅要确定输入数据…

写的一致性问题之双删模式

文章目录 1、双删模式1.1、同步双删1.2、异步双删1.3、延时双删1.4、定时双删 在事务提交前后删除两次redis&#xff0c;会有性能问题 企业开发常用&#xff1a;延时双删、异步双删 1、双删模式 1.1、同步双删 实现思路&#xff1a;AOP 1.2、异步双删 在事务提交之后异步删除r…

如何自学SQL(从入门到精通)?

SQL语言对于各个数据库是通用的&#xff0c;学习SQL数据库语言是一个系统的过程&#xff0c;可以分为几个阶段&#xff1a;入门、进阶、实践和精通。 下面是一些建议&#xff0c;可以帮助你从入门到精通自学SQL&#xff1a; 1. 学习方法 a. 理解基本概念 数据库理论&#xf…

Spring Cloud Alibaba核心组件Nacos/Seata/Sentinel

文章目录 Spring Cloud Alibaba介绍Spring Cloud 微服务体系Spring Cloud Alibaba 定位 注册配置中心--Nacos服务治理架构注册中心原理 Nacos介绍Nacos 的关键特性1.服务注册和发现2.动态配置服务3.实时健康监控4.动态DNS服务5.易于集成&#xff1a; Nacos入门示例服务注册与发…

基于微信小程序的图书馆预约占座系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的图…

【Linux】深刻理解操作系统的管理

文章目录 1.操作系统的概念&#xff08;是什么&#xff09;2.为什么要有OS&#xff08;为什么&#xff09;3.OS是如何管理的(怎么办)4.OS上层怎么用OS 1.操作系统的概念&#xff08;是什么&#xff09; 操作系统本质是&#xff1a;进行软硬件资源管理的一款软件。 操作系统包…

【第33章】Spring Cloud之SkyWalking服务链路追踪

文章目录 前言一、介绍1. 架构图2. SkyWalking APM 二、服务端和控制台1. 下载2. 解压3. 初始化数据库4. 增加驱动5. 修改后端配置6. 启动7. 访问控制台8. 数据库表 三、客户端1. 下载2. 设置java代理3. idea配置3.1 环境变量3.2 JVM参数3.3 启动日志 4. 启用网关插件 四、链路…

AI带货直播插件的五大基础功能和源代码!

随着人工智能技术的飞速发展&#xff0c;AI带货直播插件已成为电商领域的重要工具&#xff0c;这类插件通过集成先进的人工智能技术&#xff0c;不仅提升了直播的效率和互动性&#xff0c;还大大增强了用户体验和转化率。 一、AI带货直播插件的五大基础功能 ‌1、自动化内容生…

Qt 弹出菜单右键菜单 QMenu 设置不同颜色的子项

概述 在Qt中&#xff0c;可以使用样式表&#xff08;StyleSheet&#xff09;来自定义 QMenu 的外观&#xff0c;包括其子项&#xff08;如菜单项QAction&#xff09;的颜色。但是&#xff0c;这通常可以设置 QMenu 的整体样式&#xff0c;而不能单独设置某个子项的颜色。不过&…

5.安卓逆向-java面向对象

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 上一个内容&#xff1a;4.安卓逆向-常用数据结构java语言中的集合 之前的内容写了java语言常用的数据结构&#xff08…

个性化、持续性阅读 学生英语词汇量自然超越标准

2024年秋季新学年&#xff0c;根据2022版《义务教育英语课程标准》全新修订的英语新版教材开始投入使用&#xff0c;标志着我国英语教育迈入了一个以应用为导向、注重综合素养培养的新阶段。 新版教材的变革不仅仅是一次词汇量的简单增加&#xff0c;更是一场从应试到应用的深…

三菱FX5U CPU简单CPU通讯

1、与搭载以太网的模块&#xff0c;以及与通信对象设备之间进行数据通信的功能。 2、可以使用以太网端口与通信对象设备进行连接&#xff0c;并以指定的时机对指定的软元件数据进行发送和接收。3、仅通过GX Works3进行简单的参数设置&#xff0c;即可以构建无程序的通信系统。 …

共模干扰的形成和滤除

1、共模就是共同对地的干扰&#xff1a; 如图&#xff0c;我们可以看到共模的原理图。UPQ就是共模电压&#xff0c;ICM1 ICM2 就是共模电流。 ICM1 ICM2 大小不一定相同&#xff0c;方向相同。 2、共模信号和差模信号的区别&#xff1a; 通常电源线有三根线&#xff1a;火线L、…

supabase链接vecs文档

使用Supabase链接本地数据库 Vecs 如何使用本地数据库工作。确保机器上安装了Supabase CLI。 # Initialize your project supabase init# Start Postgres supabase startSupabase vecs同步数据 vecs官方文档 创建集合 import vecs #下面这一行是本地的postgre数据库连接 #…