一、 题目
二、 示例
三、思路与代码
1. 思路:
- 本题采用滑动窗口算法;(可以对比 力扣3 无重复字符的最长子串)
- 关键:本题说可以翻转0为1 k次, 来找最长的连续1的子串, 即可以换种思路:该连续1子串中包括0的个数, 不可以超过k;
- 同样套用滑动窗口算法模板:注意几个关键处理点
- right 指针往右移动扩大窗口;
- 而当窗口中0的个数超过 k 时, 进行窗口的收缩, 不断移动left指针, 直到窗口中 0 的个数不超过k;
- 而当包含连续1子串(即 “窗口”)中的0个数不超过k的时候, 进行子串长度的更新;
2. 代码如下:
- 代码中包含详细的注释;
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
// 滑动窗口 0 1 个数的记录
unordered_map<int, int> windows; // 窗口中0 1 计数器
int left = 0; // left 指针
int right = 0; // right 指针
int cnt = 0; // 连续 1 子串的长度
int n_len = nums.size();
while (right < n_len) {
int c = nums[right];
right++;
// 本题可以转换思路, 最多反转k个0, 即这一长子串中含0的个数不超过k
windows[c]++; // 无论0 或者 1 都移入窗口
// 当窗口中包含的0的个数超过了k, 则窗口收缩
while(windows[0] > k){
int d = nums[left];
left++;
if (d == 0) {
windows[d]--;
}
}
cnt = max(right - left, cnt);
}
return cnt;
}
};