滑动窗口(2)—最⼤连续1的个数III
文章目录
- 题目解析
- 方法一:二分查找
- 方法二:滑动窗口
- 附Java代码
力扣题目:最⼤连续1的个数III
题目解析
方法一:二分查找
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int n = nums.size();
vector<int> P(n + 1);
for (int i = 1; i <= n; ++i) {
P[i] = P[i - 1] + (1 - nums[i - 1]);
}
int ans = 0;
for (int right = 0; right < n; ++right) {
int left = lower_bound(P.begin(), P.end(), P[right + 1] - k) - P.begin();
ans = max(ans, right - left + 1);
}
return ans;
}
};
方法二:滑动窗口
思路与算法
我们继续观察 (1) 式,由于前缀和数组 P 是单调递增的,那么 (1) 式的右侧 P[right]−k 同样也是单调递增的。因此,我们可以发现:
随着 right 的增大,满足 (1) 式的最小的 left 值是单调递增的。
这样一来,我们就可以使用滑动窗口来实时地维护 left 和 right 了。在 right 向右移动的过程中,我们同步移动 left,直到 left 为首个(即最小的)满足 (1) 式的位置,此时我们就可以使用此区间对答案进行更新了。
class Solution {
public:
int longestOnes(vector<int>& nums, int k) {
int n = nums.size();
int left = 0, lsum = 0, rsum = 0;
int ans = 0;
for (int right = 0; right < n; ++right) {
rsum += 1 - nums[right];
while (lsum < rsum - k) {
lsum += 1 - nums[left];
++left;
}
ans = max(ans, right - left + 1);
}
return ans;
}
};
附Java代码
class Solution {
public int longestOnes(int[] nums, int k) {
int n = nums.length;
int left = 0, lsum = 0, rsum = 0;
int ans = 0;
for (int right = 0; right < n; ++right) {
rsum += 1 - nums[right];
while (lsum < rsum - k) {
lsum += 1 - nums[left];
++left;
}
ans = Math.max(ans, right - left + 1);
}
return ans;
}
}