

left和right指针指向第一个数据,并都初始化为0, 定义一个count来记录右指针“探险”时遇到的0的个数。

count++,并更新len(长度)当count>k的时候,就需要进行出窗口,将left++直到left指向的数据为0,执行count--,让count<=k后继续更新结果,直到right走到最后一个数据停止循环。

//最大连续1的个数 & 将x减到0的最小操作数
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int left = 0, ret = 0, count = 0;
for (int right = 0; right < nums.size(); right++)
{
if (nums[right] == 0) count++;
while (count > k)
{
if (nums[left++] == 0) count--;//=0的时候count--后left会++到下一个位置
}
ret = max(ret, right - left + 1);
}
return ret;
}
};//最大连续1的个数 & 将x减到0的最小操作数
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int left = 0, ret = 0, count = 0;
for (int right = 0; right < nums.size(); right++)
{
if (nums[right] == 0) count++;
while (count > k)
{
if (nums[left++] == 0) count--;//=0的时候count--后left会++到下一个位置
}
ret = max(ret, right - left + 1);
}
return ret;
}
};
int main()
{
int k1 = 2;
vector<int> nums1 = { 1,1,1,0,0,0,1,1,1,1,0 };
int result = Solution().longestOnes(nums1, k1);
cout << result << endl;
return 0;
}


x.sum减去x此时问题可以转化为:找在数组中找到最长的连续子数组,其和等于
sum - x,这样,两端的元素个数(操作次数) = n(数组长度) - 子数组长度,我们要让这个值最小,也就是让中间子数组的长度最大

sum

traget = sum-x如果目标值小于0,直接返回-1(说明数组的总和小于x)

target 的最长子数组长度 max_len初始化一个
tmp作为右指针探寻时的和,当tmp大于traget说明右指针的数据过大,需要出窗口即左指针右移直到tmp<traget,如果遇到tmp==traget就更新长度的结果,最后返回最大值。


class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int sum = 0;
for( int a:nums) sum+=a;
int traget = sum - x, left = 0, right = 0, tmp = 0, ret = -1;
if(traget < 0) return -1;//小细节
for(right = 0; right < nums.size(); right++)
{
tmp += nums[right];//进窗口
while(tmp > traget)//判断
tmp -= nums[left++];//出窗口
if(tmp == traget)
ret = max(ret , right - left + 1);//更新结果
}
if(ret == -1) return -1;//找不到返回-1
else return nums.size() - ret;//反向求,traget最大时操作数最小
}
};#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int sum = 0;
for (int a : nums) sum += a;
int traget = sum - x, left = 0, right = 0, tmp = 0, ret = -1;
if (traget < 0) return -1;//小细节
for (right = 0; right < nums.size(); right++)
{
tmp += nums[right];//进窗口
while (tmp > traget)//判断
tmp -= nums[left++];//出窗口
if (tmp == traget)
ret = max(ret, right - left + 1);//更新结果
}
if (ret == -1) return -1;//找不到返回-1
else return nums.size() - ret;//反向求,traget最大时操作数最小
}
};
int main()
{
int x1 = 5;
vector<int> nums1 = { 1,1,4,2,3};
int result = Solution().minOperations(nums1, x1);
cout << result << endl;
return 0;
}
在本篇文章中,我们通过「最大连续1的个数」与「将x减到0的最小操作数」两个经典题目,深入理解了 滑动窗口算法 的核心思想与应用方式。
🚀 敬请期待下一篇: 【C++】优选算法必修篇之双指针实战:水果成篮 & 找到字符串中所有字母异位词