1、题目解析
题目如图,通过解析题目可知,如果直接进行移除操作难度很大,因为我们不确定是减左边还是减右边,所以我们需要转换一下思维,正难则反,我们可以反着思考一下,本题是从左右两边找到最小的操作次数,那么就相当于我们需要在数组的中间找到最长的子数组,满足这个子数组的和等于数组的总大小减去X的值,如此以来难度就会小很多。
2、算法解析
本题依旧是两个解法,第一个暴力枚举直接跳过。第二个还是滑动窗口。
解题思路:
1、初始化:初始化左右指针,最长子数组的len,窗口的sum, target = 数组的总大小-X;
2、入窗口:如果sum < target, sum += nums[right];right++;
3、判断:
出窗口:如果sum > target, sum -= nums[left]; left++;
更新结果:如果sum == target; len = max(len, right - left + 1);
3、代码编写
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int len = -1;
int target = 0;
for(auto e : nums)
{
target += e;
} //初始化
target -= x;
if(target < 0)
{
return -1;
}
for(int left = 0, right = 0, sum = 0; right < nums.size(); right++)
{
sum += nums[right]; //入窗口
while(sum > target)
{
sum -= nums[left]; //判断
left++;
}
if(sum == target) //判断
{
len = max(len, right - left + 1); //更新结果
}
}
if(len == -1)
{
return -1;
}
return nums.size() - len; //返回结果
}
};