题目链接:1004. 最大连续1的个数 III - 力扣(LeetCode)
1.常规解法(会超时)
遍历数组,当元素是1时个数加一,当元素是0时且已有的0的个数不超过题目限制时,个数加一,若上述两个条件均不符合时,就退出循环,开始下一轮遍历,用len记录下最大的个数,代码如下:
java
public int longestOnes(int[] nums, int k) {
int len = 0;
int n = nums.length;
for (int i = 0; i < n; i++) {
int count = 0;
int j = i;
int distance = 0;
for (; j < n; j++) {
if (nums[j] == 1) {
distance++;
} else if (nums[j] == 0 && count < k) {
distance++;
count++;
} else {
break;
}
}
len = Math.max(len, distance);
}
return len;
}
2.滑动窗口
由常规解法可知,在第一轮遍历的时候,结果为"1 1 1 0 0",在下一轮遍历时,从第二个1开始,但由于"1 1 0 0"在第一轮遍历时已经判断为符合条件的数据,就会发生重复判断,因此,可以使用滑动窗口解决问题
先定义两个指针left和right,均指向第一个元素,再定义一个变量count记录子串中0的个数;
让right开始向后移动,当right指向的元素为1时,继续向后移动,当right指向的元素为0时,将count加一;
当count的值大于k时,就需要移动left来减少0的个数,当left指向的元素为1时,left直接向后移动,当left指向的元素为0时,让count减一,left向后移动一位,直到count与k相等时,去0结束后,记录right与left之间的距离,再继续上述操作,流程图和代码如下:
java
public int longestOnes(int[] nums, int k) {
int n = nums.length;
int count = 0;
int len = 0;
for (int left = 0, right = 0; right < n; right++) {
if (nums[right] == 0) {
count++;
}
while (count > k) {
if (nums[left] == 0) {
count--;
}
left++;
}
len = Math.max(len, right - left + 1);
}
return len;
}
希望读者给出建议!