1004. 最大连续1的个数 III

1004. 最大连续1的个数 III

题目链接:1004. 最大连续1的个数 III

题目描述

给定一个二进制数组 nums 和一个整数 k,如果可以翻转最多 k0,则返回数组中连续 1 的最大个数

核心思考:滑动窗口与状态变量转化

题意允许我们将最多 k0 翻转为 1,然后求最长全是 1 的子数组长度。如果单纯去模拟每次遇到 0 就翻转它的过程,由于存在 k 个自由额度,会产生大量复杂的分支回溯。

最优雅的破局点在于思维视角的转换
找寻“翻转不超过 k0 时最长的连续 1 数组”,在逻辑上等价于:寻找一个最长的连续子数组,其中包含的 0 的个数不得超过 k

有了这个等价转换,本题就毫无悬念地落入了**滑动窗口(Sliding Window)**的经典解题范式:

  1. 定义状态:相比于直接维护每个被消耗的 k 名额,更好维护的是窗口内元素的状态。在这个弹性区间 [left, right) 内:
    • 当前的窗口总容积是:right - left
    • 当前窗口内拥有的 1 数量记录在变量 cur_len 中。
    • 那么变相可知,当前窗口内 0 的实际个数直接等于:(right - left) - cur_len
  2. 扩大窗口:右指针 right 不断向右探索扩充疆域,如果扫瞄到 1,则同步累加核心状态值 cur_len
  3. 收缩窗口以保证合法性:一旦发现当前的子数组内 0 的数量超过了题设的阈值上限 k,说明窗口不再合法。此时必须移动左指针 left 来淘汰出局最左侧的元素,直到违背约束的状态(超出 k 限额)被解除,同时若左侧弹出的恰好是 1,别忘扣除内部状态 cur_len
  4. 提取答案:在每次成功稳住合法窗口边界时,动态更新并抓取曾经出现过的最长跨度。

解题思路 (Python)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution:
def longestOnes(self, nums: List[int], k: int) -> int:
l = len(nums)
left = right = 0
ans = 0
cur_len = 0
while right < l:
if nums[right] == 1:
cur_len += 1
right += 1
while (right - left - cur_len > k):
if nums[left] == 1:
cur_len -= 1
left +=1
ans = max(ans,right-left)
return ans

image-compressed.png

复杂度分析

  • 时间复杂度:$O(N)$,其中 $N$ 为原二进制数组 nums 的规模约束。尽管在代码结构中包含两层嵌套的 while 环向迭代,但左游标 left 和右游标 right 都始终单调向右推移,对于全体数据域的扫描总量被锁定为常数级遍历,实现严谨的线性耗散。
  • 空间复杂度:$O(1)$。通篇利用极少的几个整数形态存储(ans cur_len 加上双指针),仅依靠纯属的数值游走判定状态越界,在空间资源的统筹节约上做到了极致。