给定一个由若干 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
大概思路:
这段代码利用双指针做,通过不断移动右指针,并判断左右指针当中的 0 的数量来进行循环。如果 0 的数量大于给定条件 K,则左指针右移,右指针不动,直到区间中的 0 小于给定条件 K。
class Solution {
public static int longestOnes(int[] A, int K) {
// 双指针做法
int pLeft = 0, pRight = 0; // pLeft 为左指针, pRight 为右指针
int thisLen = 0, maxLen = 0;
int count = 0;
for( ; pRight<A.length; pRight++) { // 利用移动右指针来完成
if( count <= K ) { // 如果左、右指针所指的区间中包含的 0 的数量小于等于 K
if( A[pRight] == 0 ) { // 如果该位置的值为 0
count ++;
}
} else {
/*
* 如果包含的 0 大于 K,pRight 往回走一格(因为一旦出现0,它就会往后一个),
* 且更新长度,并在移动左指针之前判断左指针指向的值为 0 还是 1。
*/
pRight --;
thisLen = pRight - pLeft;
if( maxLen < thisLen ) maxLen = thisLen;
if( A[pLeft] == 0 ) {
count --;
}
pLeft ++;
}
}
// 最后再做一次更新,因为有可能 count 始终没有大于K就结束了循环,如:a={0,0,0,1},k=4
if( count > K && pRight == A.length ) {
// 如果此时的count>K,则意味着数组的最后一个为 0,则需要 pRight 往回一个
pRight --;
}
thisLen = pRight - pLeft;
if( maxLen < thisLen ) maxLen = thisLen;
return maxLen;
}
}
这是一个关于数组处理的问题,目标是找到一个由0和1组成的数组中,最多能翻转K个0变成1后,形成的最长连续1子数组的长度。提供的代码采用双指针策略,通过维护左指针、右指针以及区间内0的计数,动态调整区间,以达到最大长度。
454

被折叠的 条评论
为什么被折叠?



