LeetCode 485简单数组
最大连续 1 的个数 图解题解
这道题到底在问什么
给定一个只包含 0 和 1 的数组 nums(常称二进制数组),计算其中最大连续 1 的个数。连续表示位置相邻,中间不能隔 0。
- 输入
- nums = [1,1,0,1,1,1]
- 输出
- 3
- 解释
- 开头的两位和最后的三位都是连续 1,所以最大连续 1 的个数是 3。
- 边界
- [0,0] 输出 0;[1,1] 输出 2。
最优解:一步一步想明白
- 3朴素法能得到答案,但它把同一段连续 1 重复数了很多遍。题目只需要最长长度,所以更好的做法是边扫描边维护当前段长度。
- 4代码里的不变量很简单:cur 只描述当前正在延伸的这段 1,ans 记住已经见过的最大值。每个数只看一次,既不会漏末尾连续 1,也不会重复数前面的段。
- 5先读题,不执行代码先看数组形状:前面有一段长度 2 的 1,中间的 0 会把连续段切断,最后还有一段长度 3 的 1。后面代码只需要让 cur/ans 跟着这两段变化。
- 6执行:ans = 0;cur = 0ans 记录见过的最长连续 1,cur 记录当前连续 1。开局还没读元素,所以当前段长度和历史最长都是 0。
- 7执行:if x == 1 -> cur += 1 -> ans = max(ans, cur)走到代码的 if x == 1 分支。第一个数是 1,当前连续段开始了,cur 从 0 加到 1,ans 也更新为 1。
- 8执行:if x == 1 -> cur += 1 -> ans = max(1, 2)还是 if x == 1 分支。第二个数和前一个 1 相邻,所以当前段继续延长,cur=2,ans=max(1,2)=2。
- 9执行:else -> cur = 0这次走 else 分支。0 是断点,它不会让历史最长 ans 变小,只会让当前段结束,所以 cur 必须清零。
- 10执行:if x == 1 -> cur += 1 -> ans = max(2, 1)回到 if x == 1 分支。0 后面的 1 不能接到前面的段上,只能开启新段:cur=1,ans 仍然是 2。
- 11执行:if x == 1 -> cur += 1 -> ans = max(2, 2)当前段继续延长到 2,追平前面的历史最长。执行 ans=max(2,2) 后,ans 仍然是 2。
- 12执行:if x == 1 -> cur += 1 -> ans = max(2, 3)最后一个数也是 1,当前段长度变成 3。执行 ans=max(2,3),历史最长被更新为 3。
- 13执行:return ans因为每次读到 1 都立刻更新 ans,所以就算数组以 1 结尾,也不会漏掉最后一段。扫描结束直接 return ans。
- 16这题的可迁移点不是背代码,而是这三个动作:定义当前段、延续时更新、断点处重开。以后遇到“最长连续……”先套这个检查表。
⚠️ 容易写错的地方
✗ 错:把所有 1 的数量相加
✓ 对:只统计连续段长度
中间出现 0 后,前后两段不能合并。
✗ 错:遇到 0 后不清零 cur
✓ 对:else 分支必须 cur = 0
0 会切断连续 1,下一段要重新计数。
✗ 错:只在遇到 0 时更新 ans
✓ 对:每次读到 1 都更新 ans
如果数组末尾是 1,最后一段可能来不及在 0 处结算。
完整代码(Python)
Python
class Solution:
def findMaxConsecutiveOnes(self, nums):
ans = 0
cur = 0
for x in nums:
if x == 1:
cur += 1
ans = max(ans, cur)
else:
cur = 0
return ans复杂度
时间复杂度
O(n)
数组里每个元素只扫描一次。
空间复杂度
O(1)
只使用 ans 和 cur 两个计数变量。
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 最大连续 1 的个数 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
这道题为什么用「数组」,换最直接的暴力解会差在哪?+
数组抓住了本题的结构特征,把暴力解里重复的工作省掉;暴力解通常要多嵌套一层枚举,数据一大就超时。具体对比见上文「暴力解及其卡点」与「最优解逐步推演」两节。
时间复杂度为什么是 undefined?怎么推出来的?+
按上文复杂度小节的推导,时间复杂度为 undefined。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。