多语言解法全解析:暴力、单次遍历与常见陷阱)
LeetCode 485 最大连续 1 的个数Max Consecutive Ones多语言解法全解析暴力、单次遍历与常见陷阱【免费下载链接】leetcodeLeetcode solutions项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode导读本文围绕 LeetCode 485「最大连续 1 的个数」展开结合本仓库NeetCode 风格的多语言题解仓库中 articles/max-consecutive-ones.md 的完整题解脉络系统讲解暴力枚举、单次遍历两种优化写法共三种实现方案的思路、算法步骤、复杂度与代码并覆盖 Python、Java、C、JavaScript、C#、Go、Kotlin、Swift、Rust 九种语言的完整可运行实现。读完本文你将掌握「在 0/1 数组中统计最长连续 1 子段」的线性扫描技巧理解为何必须在循环结束后补做一次最终比较并能将同一思路迁移到允许翻转零的进阶变体最大连续 1 的个数 II 与 III。问题回顾与前置知识题目给定一个二进制数组nums元素只含0和1找出其中连续1的最大个数。例如nums [1,1,0,1,1,1]最长连续 1 出现在数组末尾的[1,1,1]答案为3。动手解决该题前建议先具备以下基础对应 articles/max-consecutive-ones.md 的 Prerequisites 一节数组Arrays理解如何顺序遍历并按下标访问数组元素基础迭代Basic Iteration会使用循环扫描元素并用计数器维护状态。本仓库在 README.md 中声明覆盖 Python、Java、JavaScript、C、Go、Swift、C#、TypeScript、Rust、Kotlin、Ruby、C、Scala、Dart 等语言下面给出的每种解法都保持了统一的算法骨架仅语法不同便于对照学习。解法一暴力枚举Brute Force思路Intuition对于数组中的每个位置i从它出发向后扫描统计从i开始连续有多少个1一旦遇到0或到达数组末尾就停止然后用当前计数更新全局最大值。由于每个可能起点都被检查该方案保证正确但大量子段会被重复扫描。算法步骤初始化res 0用于记录最大连续 1 的个数对每个起始下标i初始化计数器cnt 0从i向后扫描只要当前元素是1就递增cnt遇到0或到达末尾时停止用res max(res, cnt)更新结果返回res。多语言实现class Solution: def findMaxConsecutiveOnes(self, nums: List[int]) - int: n, res len(nums), 0 for i in range(n): cnt 0 for j in range(i, n): if nums[j] 0: break cnt 1 res max(res, cnt) return respublic class Solution { public int findMaxConsecutiveOnes(int[] nums) { int n nums.length, res 0; for (int i 0; i n; i) { int cnt 0; for (int j i; j n; j) { if (nums[j] 0) break; cnt; } res Math.max(res, cnt); } return res; } }class Solution { public: int findMaxConsecutiveOnes(vectorint nums) { int n nums.size(), res 0; for (int i 0; i n; i) { int cnt 0; for (int j i; j n; j) { if (nums[j] 0) break; cnt; } res max(res, cnt); } return res; } };class Solution { /** * param {number[]} nums * return {number} */ findMaxConsecutiveOnes(nums) { const n nums.length; let res 0; for (let i 0; i n; i) { let cnt 0; for (let j i; j n; j) { if (nums[j] 0) break; cnt; } res Math.max(res, cnt); } return res; } }public class Solution { public int FindMaxConsecutiveOnes(int[] nums) { int n nums.Length, res 0; for (int i 0; i n; i) { int cnt 0; for (int j i; j n; j) { if (nums[j] 0) break; cnt; } res Math.Max(res, cnt); } return res; } }func findMaxConsecutiveOnes(nums []int) int { n : len(nums) res : 0 for i : 0; i n; i { cnt : 0 for j : i; j n; j { if nums[j] 0 { break } cnt } if cnt res { res cnt } } return res }class Solution { fun findMaxConsecutiveOnes(nums: IntArray): Int { val n nums.size var res 0 for (i in 0 until n) { var cnt 0 for (j in i until n) { if (nums[j] 0) break cnt } res maxOf(res, cnt) } return res } }class Solution { func findMaxConsecutiveOnes(_ nums: [Int]) - Int { let n nums.count var res 0 for i in 0..n { var cnt 0 for j in i..n { if nums[j] 0 { break } cnt 1 } res max(res, cnt) } return res } }impl Solution { pub fn find_max_consecutive_ones(nums: Veci32) - i32 { let n nums.len(); let mut res 0; for i in 0..n { let mut cnt 0; for j in i..n { if nums[j] 0 { break; } cnt 1; } res res.max(cnt); } res } }复杂度分析时间复杂度$O(n^2)$。最坏情况如全为 1下内层循环平均扫描约 $n/2$ 个元素整体为平方级空间复杂度$O(1)$。只使用常量级额外变量res、cnt、循环下标。解法二单次遍历 IIteration - I思路Intuition事实上只需一趟扫描维护一个「当前连续 1 的计数」cnt。遇到1就递增遇到0时先用res记录下当前计数并清零cnt。由于最长序列可能恰好以数组最后一个元素结尾循环结束后还需要再做一次max(res, cnt)的最终比较。算法步骤初始化res 0、cnt 0遍历数组中的每个元素若元素为0用res max(res, cnt)更新答案并将cnt重置为0若元素为1递增cnt返回max(res, cnt)处理以数组末尾结尾的连续 1 序列。多语言实现class Solution: def findMaxConsecutiveOnes(self, nums: List[int]) - int: res cnt 0 for num in nums: if num 0: res max(res, cnt) cnt 0 else: cnt 1 return max(cnt, res)public class Solution { public int findMaxConsecutiveOnes(int[] nums) { int res 0, cnt 0; for (int num : nums) { if (num 0) { res Math.max(res, cnt); cnt 0; } else { cnt; } } return Math.max(res, cnt); } }class Solution { public: int findMaxConsecutiveOnes(vectorint nums) { int res 0, cnt 0; for (int num : nums) { if (num 0) { res max(res, cnt); cnt 0; } else { cnt; } } return max(res, cnt); } };class Solution { /** * param {number[]} nums * return {number} */ findMaxConsecutiveOnes(nums) { let res 0, cnt 0; for (const num of nums) { if (num 0) { res Math.max(res, cnt); cnt 0; } else { cnt; } } return Math.max(res, cnt); } }public class Solution { public int FindMaxConsecutiveOnes(int[] nums) { int res 0, cnt 0; foreach (int num in nums) { if (num 0) { res Math.Max(res, cnt); cnt 0; } else { cnt; } } return Math.Max(res, cnt); } }func findMaxConsecutiveOnes(nums []int) int { res, cnt : 0, 0 for _, num : range nums { if num 0 { if cnt res { res cnt } cnt 0 } else { cnt } } if cnt res { res cnt } return res }class Solution { fun findMaxConsecutiveOnes(nums: IntArray): Int { var res 0 var cnt 0 for (num in nums) { if (num 0) { res maxOf(res, cnt) cnt 0 } else { cnt } } return maxOf(res, cnt) } }class Solution { func findMaxConsecutiveOnes(_ nums: [Int]) - Int { var res 0 var cnt 0 for num in nums { if num 0 { res max(res, cnt) cnt 0 } else { cnt 1 } } return max(res, cnt) } }impl Solution { pub fn find_max_consecutive_ones(nums: Veci32) - i32 { let mut res 0; let mut cnt 0; for num in nums { if num 0 { res res.max(cnt); cnt 0; } else { cnt 1; } } res.max(cnt) } }复杂度分析时间复杂度$O(n)$单趟线性扫描空间复杂度$O(1)$。解法三单次遍历 IIIteration - II思路Intuition进一步简化逻辑把答案更新挪进循环内部每处理一个元素都执行一次res max(res, cnt)。遇到1就cnt 1否则把cnt重置为0。这样循环结束后无需再做最终比较代码更紧凑也天然规避了「忘记末尾比较」的隐患。算法步骤初始化res 0、cnt 0遍历数组中的每个元素若元素为1递增cnt否则为0将cnt置为0每步都用res max(res, cnt)更新答案返回res。多语言实现class Solution: def findMaxConsecutiveOnes(self, nums: List[int]) - int: res cnt 0 for num in nums: cnt cnt 1 if num else 0 res max(res, cnt) return respublic class Solution { public int findMaxConsecutiveOnes(int[] nums) { int res 0, cnt 0; for (int num : nums) { cnt (num 1) ? cnt 1 : 0; res Math.max(res, cnt); } return res; } }class Solution { public: int findMaxConsecutiveOnes(vectorint nums) { int res 0, cnt 0; for (int num : nums) { cnt num ? cnt 1 : 0; res max(res, cnt); } return res; } };class Solution { /** * param {number[]} nums * return {number} */ findMaxConsecutiveOnes(nums) { let res 0, cnt 0; for (const num of nums) { cnt num 1 ? cnt 1 : 0; res Math.max(res, cnt); } return res; } }public class Solution { public int FindMaxConsecutiveOnes(int[] nums) { int res 0, cnt 0; foreach (int num in nums) { cnt (num 1) ? cnt 1 : 0; res Math.Max(res, cnt); } return res; } }func findMaxConsecutiveOnes(nums []int) int { res, cnt : 0, 0 for _, num : range nums { if num 1 { cnt } else { cnt 0 } if cnt res { res cnt } } return res }class Solution { fun findMaxConsecutiveOnes(nums: IntArray): Int { var res 0 var cnt 0 for (num in nums) { cnt if (num 1) cnt 1 else 0 res maxOf(res, cnt) } return res } }class Solution { func findMaxConsecutiveOnes(_ nums: [Int]) - Int { var res 0 var cnt 0 for num in nums { cnt num 1 ? cnt 1 : 0 res max(res, cnt) } return res } }impl Solution { pub fn find_max_consecutive_ones(nums: Veci32) - i32 { let mut res 0; let mut cnt 0; for num in nums { cnt if num 1 { cnt 1 } else { 0 }; res res.max(cnt); } res } }复杂度分析时间复杂度$O(n)$空间复杂度$O(1)$。说明Python 实现中cnt cnt 1 if num else 0依赖0的假值特性Java/C/C#/Swift 等语言则显式写成num 1的三目表达式两种写法语义等价。三种解法对比解法核心思想时间复杂度空间复杂度特点暴力枚举对每个起点向后统计连续 1$O(n^2)$$O(1)$直观、易写但重复扫描大量子段单次遍历 I遇 0 更新并清零循环后补一次比较$O(n)$$O(1)$思路清晰注意末尾比较单次遍历 II每步更新答案遇 0 置零$O(n)$$O(1)$代码最紧凑无末尾比较从源码结构看本仓库对同一问题在不同语言中保持了完全一致的解法骨架变量名res/cnt、max更新方式例如 scala/0485-max-consecutive-ones.scala 用函数式风格把「单次遍历 II」浓缩成一行object Solution { def findMaxConsecutiveOnes(nums: Array[Int]): Int nums.scanLeft(0)((m, x) if (x 0) 0 else m 1).max }scanLeft(0)(...)对每个前缀位置计算「以该位置结尾的连续 1 个数」遇到0归零否则累加对得到的前缀序列取max即为答案。这与迭代写法的语义完全一致可作为理解「每步维护以当前位置结尾的连续 1 长度」这一核心状态的辅助视角。常见陷阱Common Pitfallsarticles/max-consecutive-ones.md 专门总结了两个高频错误点面试与编码时需格外留意。陷阱一忘记循环结束后的最终比较采用「遇 0 才更新答案」的写法解法二时最长连续 1 序列可能正好以数组最后一个元素结尾此时循环体内不会触发「遇到 0」的分支res就永远不会被更新。例如nums [1,1,1]遍历结束cnt 3而res仍是0若直接return res得到错误答案0。修正方法循环结束后补max(res, cnt)或者干脆采用解法三——每步都更新res从根源上消除该问题。陷阱二计数器重置错误更隐蔽的 bug 是遇到0时把计数器重置为1而非0或者「先递增再判断当前元素」。正确语义是遇到0时cnt 0这样后续遇到的第一个1会把计数递增回1若把0也计入重置为1会引入 off-by-one 误差导致结果虚高。例如nums [0,1]若遇0时错误地cnt 1则最终答案为1而非正确答案1之前…… 更典型的反例是nums [1,0,1,1]若遇0时cnt 1则扫描到0后res记录1正确应为 1因为0前后两段连续 1 并不相邻不能合并而后续[1,1]正确计数为2最终答案仍为2看似没出错——但在nums [1,0,1]且错误计数不归零的情况下若把0计入连续段就可能把不相邻的两段 1 错误合并。判断标准很简单0永远是断点断点处计数必须归零。延伸与相关题解「最长连续 1」是一系列滑动窗口/双指针题的基础。本仓库还收录了两个进阶变体建议按顺序练习articles/max-consecutive-ones-ii.md最大连续 1 的个数 II——允许将至多 1 个0翻转成1求翻转后最长连续 1 的长度。思路从「计数重置」升级为「维护窗口内 0 的个数 ≤ 1」对应前置知识中的 Sliding Window 与 Two Pointersarticles/max-consecutive-ones-iii.md最大连续 1 的个数 III——允许翻转至多 k 个0是 II 的一般化版本把「0 的个数 ≤ 1」推广为「0 的个数 ≤ k」。掌握本题的线性扫描后再理解这两个变体的窗口伸缩逻辑会非常顺畅本题是「窗口内 0 的个数必须为 0」的特例即k 0。小结暴力枚举$O(n^2)$适合验证正确性但不适合大数据量单次遍历$O(n)$、$O(1)$是本题的标答两种写法分别演示了「循环后补比较」与「循环内持续更新」两种风格后者更不易出错核心心智模型cnt永远表示「以当前位置结尾的连续 1 的长度」遇到0就归零。该模型可直接推广到滑动窗口类变体题目。如需在本地验证以上实现可参考 README.md 中仓库的组织方式各语言解答按题号-题名.扩展名命名如 scala/0485-max-consecutive-ones.scala对照 articles/max-consecutive-ones.md 与进阶题解 max-consecutive-ones-ii、max-consecutive-ones-iii 即可形成完整的「基础 → 滑动窗口 → 一般化 k」学习链路。【免费下载链接】leetcodeLeetcode solutions项目地址: https://gitcode.com/GitHub_Trending/leetcode1/leetcode创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考