题目示例
示例 1
- 输入:nums = [1,1,0,1,1,1]
- 输出:3
- 解释: 开头的两位和最后的三位都是连续1,所以最大连续1的个数是3。
示例 2
- 输入:nums = [1,0,1,1,0,1]
- 输出:2
提示
- 1 <= nums.length <= 10^5
- nums[i]不是0就是1。
题解 (原始代码)
class Solution {
public int findMaxConsecutiveOnes(int[] nums) {
int max = 0;
int t = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 1) {
t++;
} else {
if (t > max) {
max = t;
}
t = 0;
}
}
if (t > max) {
max = t;
}
return max;
}
}
知识点识别
本题主要考察的知识点是:
- 主要算法类别:
- 数组遍历(Array Traversal)/ 线性扫描(Linear Scan): 算法的核心是通过一次遍历(单次迭代)数组来解决问题。
- 简单计数/状态维护: 在遍历过程中,需要实时维护一个计数器来跟踪当前连续1的长度。
- 数据结构:
- 数组(Array): 输入数据的基本结构。
总而言之,这是一个典型的利用 O(n) 时间复杂度 线性扫描数组来解决的问题,没有涉及复杂的数据结构或高级算法技巧。
解题过程描述
核心思路:迭代与状态维护
该题解采用的核心思想是 线性扫描,即从数组的开始到结束,逐个检查每个元素,并使用两个变量来维护和更新必要的状态:
- t(当前计数器/Current Count): 用于记录到目前为止,当前正在遍历的连续1的个数。
- max(最大值/Maximum): 用于记录整个数组中出现过的最大连续1的个数。
详细步骤分析
- 初始化:
- max初始化为0:表明当前找到的最大连续1的长度。
- t初始化为0:表明当前连续1的长度。
- 主循环(遍历数组): 遍历数组nums的每一个元素nums[i]。
- 情况 A:如果nums[i] == 1: 当前连续序列继续延长,将当前计数器t增加 1 (t++)。
- 情况 B:如果nums[i] == 0: 连续序列中断。
- 更新最大值:将当前的t与总最大值max进行比较,如果t > max,则更新max = t。
- 重置计数器:由于序列已中断,将当前计数器t重置为0,准备开始计算下一个可能的连续1序列。
- 循环结束后的处理(重大):
- 循环结束后,数组的最后一个连续1序列的长度可能存储在变量t中,但尚未与max进行比较。
- 因此,需要在循环体外部再次进行一次最大值更新:if (t > max) { max = t; }。
- 最终返回max作为结果。
复杂度分析
1. 时间复杂度
- O(n),其中 n 是数组nums的长度。
- 理由: 算法只涉及一次完整的数组遍历(一个for循环),循环体内的操作都是 O(1) 的基本操作。因此,运行时间与数组长度成线性关系。
2. 空间复杂度
- O(1)。
- 理由: 算法只使用了固定的额外空间来存储几个变量(max和t),这些变量的数量不随输入数组的大小 n 变化。
题解有效性与优化提议
该题解的思路是完全正确且高效的,通过一次遍历就解决了问题,达到了最优的时间复杂度 O(n)。
代码优化提议 (简洁性)
你提供的代码清晰且易于理解。对于循环结束后的边界情况处理,可以采用在循环内部进行最大值更新的写法来简化代码(逻辑和效率不变):
// 优化后的简洁写法示例 (Java)
public int findMaxConsecutiveOnes_Optimized(int[] nums) {
int max = 0;
int current = 0; // 改用 current 命名更清晰
for (int num : nums) {
if (num == 1) {
current++;
// 每次 current 增加后,都立即与 max 比较并更新
// 这样就避免了在循环结束后额外的 if 判断
max = Math.max(max, current);
} else {
// 遇到 0,重置当前计数器
current = 0;
}
}
return max;
}
© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END
















暂无评论内容