LeetCode 1004.最大连续1的个数III 滑动窗口及动态规划题解
一、题目描述给定一个二进制数组nums和一个整数k假设最多可以翻转k个0则返回执行操作后数组中连续 1 的最大个数。示例 1输入nums [1,1,1,0,0,0,1,1,1,1,0], K 2 输出6 解释[1,1,1,0,0,1,1,1,1,1,1] 粗体数字从 0 翻转到 1最长的子数组长度为 6。示例 2输入nums [0,0,1,1,0,0,1,1,1,0,1,1,0,0,0,1,1,1,1], K 3 输出10 解释[0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1] 粗体数字从 0 翻转到 1最长的子数组长度为 10。提示1 nums.length 10^5nums[i]不是 0 就是 10 k nums.length二、题目本质分析这道题表面上是在问翻转 k 个 0 后能得到多长的连续 1但换个角度理解等价于在一个二进制数组中找到一个最长的子数组使得子数组中 0 的个数不超过 k。这个转化非常关键因为翻转 k 个 0实际上就是允许窗口内出现最多 k 个 0。一旦想清楚这一点问题就变成了求满足条件的最长子数组长度而这类问题有两个经典解法滑动窗口双指针—— 最优解O(n)动态规划—— 辅助理解O(n·k)三、法一滑动窗口3.1 核心思路维护一个窗口[left, right]保证窗口内0的个数不超过k。右指针right扩张每次把nums[right]加入窗口如果是 0则zeroCount。当窗口内 0 的个数超过 k 时说明窗口不合法需要左指针left收缩直到zeroCount k。收缩时如果移出的是 0则zeroCount--。每次窗口合法时用right - left 1更新答案。3.2 图示理解以示例 1 为例nums [1,1,1,0,0,0,1,1,1,1,0], k 2初始: left0, right0, zeroCount0 右扩: [1] zeroCount0, 合法, ans1 右扩: [1,1] zeroCount0, 合法, ans2 右扩: [1,1,1] zeroCount0, 合法, ans3 右扩: [1,1,1,0] zeroCount1, 合法, ans4 右扩: [1,1,1,0,0] zeroCount2, 合法, ans5 右扩: [1,1,1,0,0,0] zeroCount3, 不合法 收缩: [1,1,0,0,0] 移出1 zeroCount3, 仍不合法 收缩: [1,0,0,0] 移出1 zeroCount3, 仍不合法 收缩: [0,0,0] 移出1 zeroCount3, 仍不合法 收缩: [0,0,0] 移出0 zeroCount2, 合法 右扩: [0,0,0,1] zeroCount2, 合法, ans4 右扩: [0,0,0,1,1] zeroCount2, 合法, ans5 ...以此类推 最终最长窗口: [0,0,1,1,1,1,1,1] (长度 6)3.3 代码实现Cclass Solution { public: int longestOnes(vectorint nums, int k) { int left 0, right 0; int zeroCount 0; // 当前窗口内 0 的个数 int maxLen 0; while (right nums.size()) { // 右指针元素进入窗口 if (nums[right] 0) { zeroCount; } // 如果窗口内 0 的个数超过 k左指针收缩 while (zeroCount k) { if (nums[left] 0) { zeroCount--; } left; } // 更新最大长度 maxLen max(maxLen, right - left 1); right; } return maxLen; } };3.4 复杂度分析时间复杂度O(n)。left和right各自最多向右移动 n 次总移动次数不超过 2n。空间复杂度O(1)。只使用常数个变量。四、法二动态规划会超出内存限制4.1 为什么可以用 DP滑动窗口是空间上的贪心而 DP 是另一种思路从每个位置出发思考以该位置结尾的最长合法子数组能有多长。4.2 状态定义定义dp[i][j]表示以nums[i]为结尾且恰好使用了j次翻转机会时能得到的最长连续 1 的长度。这里的恰好使用 j 次是指最多可以使用 j 次因为翻不翻是灵活的但为了状态统一我们约定j表示预算遇到 0 就消耗一次。4.3 状态转移方程分两种情况讨论情况 1nums[i] 1不需要消耗翻转次数直接延长前一个状态即可dp[i][j] dp[i-1][j] 1情况 2nums[i] 0必须消耗一次翻转机会如果j 0还有翻转次数则dp[i][j] dp[i-1][j-1] 1如果j 0没有翻转次数了遇到 0 只能断掉dp[i][j] 04.4 为什么以 i 结尾很重要因为题目要求的是连续子数组。定义状态时明确以nums[i]结尾转移时才能强制连续。如果定义成dp[i][j]为前 i 个元素中的最长连续 1就无法正确转移因为子数组可能从前面的某个位置开始不一定包含nums[i]。4.5 初始化dp数组大小为(n1) × (k1)全部初始化为 0。dp[0][*] 0表示还没有元素长度为 0。遍历时i从 1 到 nj从 0 到 k。4.6 代码实现Cclass Solution { public: int longestOnes(vectorint nums, int k) { int n nums.size(); // dp[i][j] 表示以 i 结尾用了 j 次翻转的最大长度 vectorvectorint dp(n 1, vectorint(k 1, 0)); int ans 0; for (int i 1; i n; i) { for (int j 0; j k; j) { if (nums[i - 1] 1) { dp[i][j] dp[i - 1][j] 1; } else { // nums[i-1] 0 if (j 0) { dp[i][j] dp[i - 1][j - 1] 1; } else { dp[i][j] 0; // 没有翻转次数了遇到0只能断 } } ans max(ans, dp[i][j]); } } return ans; } };4.7 举例演示以nums [1,1,1,0,0,0,1,1,1,1,0], k 2为例展示部分 DP 过程inums[i-1]j0j1j2111112122231333400445001560002711138122491335101446110055最后答案取所有dp[i][j]的最大值即6。4.8 复杂度分析时间复杂度O(n·k)。双重循环外层 n内层 k。空间复杂度O(n·k)。二维数组

相关新闻

【算法题目练习】找出字符串中第一个匹配项的下标

【算法题目练习】找出字符串中第一个匹配项的下标

题目:解题:结果:思路:一、读题目给定两个字符串 haystack(主串)、needle(子串)在主串里找到第一次完整出现子串的起始下标(下标从 0 开始)如果找不到&#xf…

2026/10/24 8:57:17 阅读更多 →
头歌Python沙箱环境运行机制深度解析

头歌Python沙箱环境运行机制深度解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/25 21:57:48 阅读更多 →
电机控制入门:一文读懂磁链

电机控制入门:一文读懂磁链

title: “电机控制入门:一文读懂磁链” date: 2026-10-02 categories: 电机控制 tags:磁链FOCPMSM反电动势弱磁控制 description: “从磁通、磁链和电感的关系出发,直观理解磁链如何产生感应电压、参与转矩形成,以及它在 FOC 和弱磁控制中的作…

2026/11/10 6:08:41 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/10 23:32:01 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/10 23:32:03 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/11 2:31:33 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/10 16:14:15 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/10 12:51:50 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/10 23:32:10 阅读更多 →

日新闻

周新闻

月新闻