题目
- 给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 。返回仅包含 1 的最长(连续)子数组的长度。
- 示例 1:
输入:A = [1,1,1,0,0,0,1,1,1,1,0], K = 2
输出:6
解释: [1,1,1,0,0,1,1,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 6。 - 示例 2:
输入:A = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K = 3
输出:10
解释:[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1]
粗体数字从 0 翻转到 1,最长的子数组长度为 10。 - 提示:
1 <= A.length <= 20000
0 <= K <= A.length
A[i] 为 0 或 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/max-consecutive-ones-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
方法
class Solution {
public int longestOnes(int[] A, int K) {
int max = 0;
//双指针从零开始遍历
for (int left = 0, right = 0; right < A.length; right++) {
//当右指针的数组元素为零判断K;
if (A[right] == 0) {
//当k==0,此时左指针左滑到跳过它的一个零为止
if (K == 0) {
//跳过满足1的情况
while (A[left] == 1) {
left++;
}
//跳过第一个零的情况,此时满足了k==0
left++;
} else {
//K不等于0则k--;
K--;
}
}
//最大值取左右区间的最大值
max = right - left + 1 > max ? right - left + 1 : max;
}
//返回max;
return max;
}
}
/*//超时
Set<Integer>set = new HashSet<>();
int result =0;
for(int i =0;i<A.length;i++){
set.clear();
int flag = 0;
int count = 0;
set.add(1);
for(int j=i;j<A.length;j++){
if(set.contains(A[j])){
count++;
result =Math.max(result,count);
}
if(!set.contains(A[j])&&flag<K){
flag++;
count++;
result =Math.max(result,count);
}
if(flag==K){
result =Math.max(result,count);
break;
}
}
}
return result;
*/
思路
-
使用双指针 left 和 right 指代窗口的左右边界,移动 right 指针遍历整个数组,同时维护一个变量 max,每次 right 移动计算一次当前的最大值。
-
分析:
分为以下几种情况:- 当 A[right] = 1 时,left 不变,right 继续移动
- 当 A[right] = 0 时,0 的数量在 K 的范围内,left 不变,right 继续移动0 的数量 > K,
- 当 A[left] == 0 时,即 left 指向了一个零,只需要 left 右移一格,就可以减少一个零
- 当 A[left] == 1 时,即此时窗口内包了 K 个零,需要先移动至下个零,再右移一格才能减少一个零
下一步总结
- 没太懂这种思路
- 总结这种思路的规律