leetcode
leetcode 901 ~ 950
最大连续1的个数 III

最大连续1的个数 III

难度:

标签:

题目描述

代码结果

运行时间: 54 ms, 内存: 16.7 MB


/*
题目思路:
使用滑动窗口的方法来解决这个问题。虽然Java Stream API并不适合处理需要保持状态和
在多次迭代之间进行复杂状态维护的问题,但我们仍然可以使用基本的Java和少量的Stream API
来实现这个算法。
*/

import java.util.Arrays;
import java.util.stream.IntStream;

public class Solution {
    public int longestOnes(int[] nums, int k) {
        int left = 0, right = 0;
        int maxLength = 0;
        int zerosCount = 0;
        while (right < nums.length) {
            if (nums[right] == 0) {
                zerosCount++;
            }
            while (zerosCount > k) {
                if (nums[left] == 0) {
                    zerosCount--;
                }
                left++;
            }
            maxLength = Math.max(maxLength, right - left + 1);
            right++;
        }
        return maxLength;
    }
}

解释

方法:

本题解使用滑动窗口的策略,通过遍历数组维护一个窗口,该窗口可以包含最多 k 个 0 和任意数量的 1。遍历数组 nums 时,如果遇到 0,则增加 zero 计数器。如果 zero 计数器超过 k,表示当前窗口不满足条件,此时需要调整窗口的左边界 j,直到窗口内的 0 的数量不超过 k 为止。最终,窗口的最大宽度即为数组中可以通过翻转最多 k 个 0 而形成的最长连续 1 的长度。

时间复杂度:

O(n)

空间复杂度:

O(1)

代码细节讲解

🦆
在滑动窗口策略中,如何确定何时需要移动窗口的左边界以保持窗口内最多包含k个0?
在滑动窗口策略中,当数组中的0的数量(由变量zero计数)超过了k时,需要移动窗口的左边界。这是因为窗口内最多只能包含k个0,以满足题目条件。如果zero计数超过k,就从窗口左端开始移除元素,直到窗口中的0的数量再次等于或小于k。这通常通过增加左边界索引j来实现,如果移除的元素是0,则相应地减少zero计数。
🦆
如果数组中所有元素都是0,且k小于数组长度,这种情况下算法的输出是什么?
如果数组中所有元素都是0,并且k小于数组长度,算法的输出将是k。这是因为算法可以将最多k个0翻转为1,从而在数组中形成一个由k个连续1组成的序列。由于窗口的长度不能超过数组长度,且最多只能翻转k个0,因此最长的连续1序列的长度即为k。
🦆
在调整窗口左边界时,你是如何确保减少的zero计数器总是对应于窗口左端的0而非1?
在调整窗口左边界时,算法会检查左边界索引j所指向的元素。如果这个元素是0,则在移动窗口左边界(即增加j的值)之前,将zero计数器减1。如果元素是1,则直接移动左边界,不对zero计数器做任何调整。这样可以确保zero计数器的减少总是与窗口左端被移除的0相对应。
🦆
为什么在计算最长连续1的长度时,使用了`len(nums) - j`这种计算方式?这是否考虑了窗口内可能的1的数量?
使用`len(nums) - j`计算方式是因为在遍历数组结束时,j代表了最终确定的、可以满足条件的窗口的左边界的位置。`len(nums) - j`表示从索引j到数组结束的距离,即窗口的大小。这种计算方式假设从j到数组末尾的部分都可以通过翻转不超过k个0来形成连续的1。因此,这种计算方式考虑了窗口内可能的1的数量,并且假设最优情况下,窗口内所有的0都被翻转成了1。

相关问题

至多包含 K 个不同字符的最长子串

至多包含 K 个不同字符的最长子串

替换后的最长重复字符

给你一个字符串 s 和一个整数 k 。你可以选择字符串中的任一字符,并将其更改为任何其他大写英文字符。该操作最多可执行 k 次。

在执行上述操作后,返回 包含相同字母的最长子字符串的长度。

 

示例 1:

输入:s = "ABAB", k = 2
输出:4
解释:用两个'A'替换为两个'B',反之亦然。

示例 2:

输入:s = "AABABBA", k = 1
输出:4
解释:
将中间的一个'A'替换为'B',字符串变为 "AABBBBA"。
子串 "BBBB" 有最长重复字母, 答案为 4。
可能存在其他的方法来得到同样的结果。

 

提示:

  • 1 <= s.length <= 105
  • s 仅由大写英文字母组成
  • 0 <= k <= s.length

最大连续 1 的个数

给定一个二进制数组 nums , 计算其中最大连续 1 的个数。

 

示例 1:

输入:nums = [1,1,0,1,1,1]
输出:3
解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.

示例 2:

输入:nums = [1,0,1,1,0,1]
输出:2

 

提示:

  • 1 <= nums.length <= 105
  • nums[i] 不是 0 就是 1.

最大连续1的个数 II

最大连续1的个数 II