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=0cnt=0ans=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=1cnt还是3(因为nums[0]是1)~
    • 再挪到l=2cnt还是3(nums[1]是1)~
    • 再挪到l=3nums[2]是1,cnt还是3~
    • 最后挪到l=4nums[3]是0,cnt=2,这时候窗口长度是5-4+1=2,但ans还是5~
  8. 后面继续走,到i=9的时候,窗口长度能到6,最终ans=6,符合示例~

总结

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

相关推荐
naruto_lnq16 小时前
分布式系统安全通信
开发语言·c++·算法
Jasmine_llq16 小时前
《P3157 [CQOI2011] 动态逆序对》
算法·cdq 分治·动态问题静态化+双向偏序统计·树状数组(高效统计元素大小关系·排序算法(预处理偏序和时间戳)·前缀和(合并单个贡献为总逆序对·动态问题静态化
爱吃rabbit的mq17 小时前
第09章:随机森林:集成学习的威力
算法·随机森林·集成学习
(❁´◡`❁)Jimmy(❁´◡`❁)18 小时前
Exgcd 学习笔记
笔记·学习·算法
YYuCChi18 小时前
代码随想录算法训练营第三十七天 | 52.携带研究材料(卡码网)、518.零钱兑换||、377.组合总和IV、57.爬楼梯(卡码网)
算法·动态规划
不能隔夜的咖喱18 小时前
牛客网刷题(2)
java·开发语言·算法
VT.馒头18 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
进击的小头19 小时前
实战案例:51单片机低功耗场景下的简易滤波实现
c语言·单片机·算法·51单片机
咖丨喱20 小时前
IP校验和算法解析与实现
网络·tcp/ip·算法
罗湖老棍子20 小时前
括号配对(信息学奥赛一本通- P1572)
算法·动态规划·区间dp·字符串匹配·区间动态规划