Day63 | 灵神 | 滑动窗口:将x减到0的最小操作数

1658.将x减到0的最小操作数

1658. 将 x 减到 0 的最小操作数 - 力扣(LeetCode)

思路:

这道题笔者没什么思路,直接做的,答案是错误的,遗憾落泪

就去看了灵神的思路

要逆向思维,把这道题转化为滑动窗口的题,先求出数组和再减去x,这个数字表示为sum,这时候我们要求的就是在数组中找一个最长子数组,使得这个子数组的和等于sum,然后再用数组长度减去最长子数组长度就是我们要的最小操作数了

说实话我想不出来

既然知道了这个思路

还是继续前几天的核心思路,固定右端点,遍历右端点,然后寻找左指针收缩条件

这道题左指针收缩条件得根据我们转换后的思维来写,不能通过原来的题目得出这个收缩条件

根据我们的思路,左指针收缩条件那就是当前子数组的和大于sum这个数,我们就收缩左指针,从而减小子数组的和,来和sum进行比较

如果正好等于sum才是满足条件的情况,才会去更新最后的结果

子数组的长度还是(r-l+1)

下面看完整代码

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int res=-1,l=0,temp=0;
//得到我们的最长子数组的和要相等的数字
int sum=reduce(nums.begin(), nums.end())-x;
//如果一开始sum就小于0,说明整个数组都减了也不能达到x
if (sum<0) {
return -1;
}
for(int i=0;i<nums.size();i++)
{
//记录子数组的和
temp+=nums[i];
//左指针收缩
while(temp>sum)
{
temp-=nums[l];
l++;
}
//满足条件的情况,更新答案
if(temp==sum)
res=max(res,i-l+1);
}
//返回结果
if(res==-1)
return -1;
else
return nums.size()-res;
}
};