模块二——滑动窗口:1658.将x减到0的最小操作数

一、题目解析

题目链接:1658.将x减到0的最小操作数
在这里插入图片描述
这道题的意思是让我们求出x - (每次取数组最左边或者最右边的值) -> 0的最小操作次数并返回,否则返回-1。(PS:最左边和最右边的操作可以为0)

二、算法原理

题⽬要求的是数组「左端+右端」两段连续的、和为 x 的最短数组,信息量稍微多⼀些,不易理清思路;我们可以转化成求数组内⼀段连续的、和为sum(nums) - x 的最⻓数组。此时,就是熟悉的「滑动窗⼝」问题了。
在这里插入图片描述
初始化左右指针left = 0 ,right = 0 (滑动窗⼝区间表⽰为[left,right) ,左右区间是否开闭很重要,必须设定与代码⼀致),当target<0时问题无解(数组总和小于x则再怎么减都无法减到0)。

三、代码编写

解法一:暴力枚举(超时)

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        //暴力枚举
        int n = nums.size(),numsSum = 0,minOp = 0;
        for(int i = 0;i < n;i++)
        {
            numsSum += nums[i];//求数组的总和
        }
        int target = numsSum - x;//target记录numsSum-x
        if(target < 0)return -1;
        else if(target == 0)return n;
        for(int left = 0;left < n;left++)
        {
            int sum = 0;//记录left到right的总和
            for(int right = left;right < n;right++)
            {
                sum += nums[right];
                if(target == sum)minOp = max(minOp,right - left + 1);
            }
        }
        if(minOp == 0)return -1;
        else return n - minOp;
    }
};

解法二:滑动窗口(时间复杂度是O(n),空间复杂度是O(1))

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
      //滑动窗口
      int n = nums.size(),minOp = -1,sum = 0;
      int numsSum = accumulate(nums.begin(), nums.end(), 0);//记录数组总和

      int target = numsSum - x;//转化问题
      if(target < 0)return -1;
      for(int left = 0,right = 0;right < n;right++)
      {
          sum += nums[right];//进窗口
          while(sum > target)//判断
          sum -= nums[left++];
          if(target == sum)minOp = max(minOp,right - left + 1);//更新结果
      }
      if(minOp == -1)return -1;
      else return n - minOp;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全天

加油,大佬们!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值