专题二_滑动窗口_最大连续1的个数
一:题目
解释:你能任意选择数组中的k个0,让这k个0都变成1,题目要你返回连续1的最大个数
正向解题:
这道题目,从正面解决很麻烦,你不能保证你把选择的0变成1之后,此时数组中的连续1的最大个数就是正确答案,不是正确答案,则你还需将变为1的元素变回0,所以很麻烦!
反向解题:
我找一个最长的子串,这个子串里面0的个数<=k即可!
我根本不用去将0变成1,我直接找一个子串,我控制好这个子串中0的个数,<=翻转的机会k次就好了!
所以这个题目用滑动窗口我们只用检测窗口内0的个数是否超过了k即可
注:有时候最长的子串,可能其中的0的个数,并不会达到k个,所以,只用要求子串中0的个数<=k即可,强制要求0的个数==k,是必然会错的
例子:
nums = [1,1,1,0,1,1,1], k = 2 //这种时候0的个数永远不可能==k
二:算法
①:暴力
N^2,依旧是left不断的++作为新的起点位置,然后right从left+1的位置开始向后遍历,窗口内0的个数<=k则更新长度,反之0的个数>k了,则left++,right从left+1的位置再此开始遍历
②:滑动窗口
暴力能优化的点:
1:当窗口内0的个数超过k的时候 left应该直接走到第一个0的后面!
2:执行1之后,right也不用再回到left+1的位置,因为此时窗口中0的个数一定==k,所以right只需继续向后判断
三:代码
class Solution {
public:int longestOnes(vector<int>& nums, int k) {int ret = 0;//返回值在for外定义for (int left = 0, right = 0, zero = 0; right < nums.size(); right++) {if (nums[right] == 0) zero++;//进窗口 元素为0 则计数器++while (zero > k) //窗口不符合题目要求{if (nums[left++] == 0) zero--;//不断的出窗口 直到符合题目要求}ret = max(ret, right - left + 1);//判断更新返回值}return ret;}
};
易错点:
判断更新返回值,一定是在窗口符合题目要求的时候,去进行的,而while循环内部的窗口是不符合题目要求的,所以判断更新这一步一定是在while循环外面进行的!