LeetCode 1004. 最大连续1的个数 III

题目链接

1004. 最大连续1的个数 III

题目描述

宝子们,给你们一个二进制数组 nums 和一个整数 k,咱们要找最长的连续1的子数组长度哦~不过呢,允许最多把 k 个0翻成1,是不是很有意思?快来看看怎么解决吧~

示例

  • 输入:nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2

    • 输出:6
    • 解释:把前两个0翻成1,就得到超长的1序列啦,长度直接到6~
  • 输入:nums = [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], k = 3

    • 输出:10
    • 解释:翻三个0之后,连续1的长度直接干到10,爽不爽~

解法分析:滑动窗口法

核心思路

这里咱们用滑动窗口(双指针)来解决,思路超简单:维护一个窗口,保证里面最多有 k 个0。窗口越大,能翻成的连续1就越长~具体怎么操作呢?往下看~

代码实现

python 复制代码
class Solution:
    def longestOnes(self, nums: List[int], k: int) -> int:
        l = ans = cnt = 0
        for i in range(len(nums)):
            # 统计窗口里有多少个0,0的话cnt+1,1的话不变
            cnt += nums[i] ^ 1
            # 如果0太多了(超过k个),就把左指针往右移
            while cnt > k:
                cnt -= nums[l] ^ 1
                l += 1
            # 随时更新最长连续1的长度
            ans = max(ans, i - l + 1)
        return ans

代码解析

  1. 初始化变量:

    • l 是左指针,初始位置0,用来缩窗口的~
    • ans 存最长连续1的长度,初始为0,后面慢慢更新~
    • cnt 数窗口里有多少个0,初始也是0~
  2. 遍历数组:

    • 右指针 i 从左到右走,每到一个位置,看看是不是0:
      • 是0的话,cnt += 1(用nums[i] ^ 1算,超方便~)
      • 是1的话,cnt 不变~
  3. 调整窗口:

    • 如果cnt超过k了,说明窗口里0太多啦,得把左指针l右移:
      • 左指针位置的数如果是0,cnt -= 1
      • 左指针挪一步,窗口变小~
  4. 更新最长长度:

    • 每次都算一下当前窗口长度i - l + 1,和之前的ans比,取大的那个~

关键技巧说明

  1. 位运算yyds :用nums[i] ^ 1判断是不是0,0 ^ 1=1(加1),1 ^ 1=0(不加),是不是超简洁~

  2. 滑动窗口怎么玩:

    • 右指针疯狂扩展窗口,左指针看情况收缩,保证窗口里最多k个0~
    • 这样一来,窗口里的0都翻成1之后,不就是连续1嘛~
  3. 窗口长度计算 :i - l + 1就是当前窗口长度,因为左闭右闭区间呀~

示例详解

以输入nums = [1,1,1,0,0,0,1,1,1,1,0], k = 2为例,咱们一步步看:

  1. 刚开始l=0,cnt=0,ans=0~
  2. i=0,数是1,cnt还是0,窗口长度1,ans=1~
  3. i=1,数是1,cnt还是0,窗口长度2,ans=2~
  4. i=2,数是1,cnt还是0,窗口长度3,ans=3~
  5. i=3,数是0,cnt=1,窗口长度4,ans=4~
  6. i=4,数是0,cnt=2,窗口长度5,ans=5~
  7. i=5,数是0,cnt=3(超过k=2啦!),这时候左指针开始挪:
    • 先挪到l=1,cnt还是3(因为nums[0]是1)~
    • 再挪到l=2,cnt还是3(nums[1]是1)~
    • 再挪到l=3,nums[2]是1,cnt还是3~
    • 最后挪到l=4,nums[3]是0,cnt=2,这时候窗口长度是5-4+1=2,但ans还是5~
  8. 后面继续走,到i=9的时候,窗口长度能到6,最终ans=6,符合示例~

总结

这个解法用滑动窗口超高效,时间复杂度O(n),空间复杂度O(1)~核心就是保持窗口里的0不超过k个,这样翻完就是连续1啦~宝子们学会了吗?遇到类似"最多改k个元素"的题,试试滑动窗口,超好用哦~

相关推荐
其实防守也摸鱼4 分钟前
Cylab在线靶场——CTF中的通用技能
linux·数据库·学习·算法·靶场·ctf·学习网络安全
蓝悦无人机20 分钟前
《Planning algorithms》读书笔记——第8章 反馈运动规划
算法·读书笔记·反馈运动规划
RaaS10037 分钟前
Agent Skills 进了 Linux Foundation:2.8 亿次安装,但装 skill 还没有安全规范
人工智能·算法·架构
CV爱数码1 小时前
CT 重建从零开始(五):ASTRA Toolbox 上手——几何、投影器与算法
图像处理·算法·计算机视觉·ct
TunerT_TQ1 小时前
超立方体Ramsey(openai/math 家族171)H11攻坚日志|D60–D69:Star分组重数、二幂坐标群、奇偶入射语义与Site‑Level候选计数形式化闭环
算法
Rabitebla1 小时前
【系统性学习笔记】Linux 权限篇(二):文件属性、权限修改与目录权限的底层逻辑
linux·c++·笔记·学习·算法
远离UE42 小时前
半拉格朗日学习笔记 动力学 实时渲染
人工智能·算法
小郎君6582 小时前
MPTT 不是万能编号:一棵百万节点树的增删改与批量事务
算法
FPGA小徐2 小时前
【一生一芯 / PA】AM 核心文件逐行解析(上):从 start.S 到 gpu.c
前端·算法
Tairitsu_H3 小时前
[动态规划#1] 子数组 | 最大子数组和 | 环形子数组的最大和 | 乘积最大子数组 | 乘积为正数的最长子数组
算法·动态规划