问题描述

给定一个二进制数组 nums,计算其中最大连续 1 的个数。

解题思路

本题是经典的遍历 + 计数器问题,思路直接但需要注意边界处理。

单指针遍历法

使用两个变量:

  • pre_sum:当前连续 1 的计数
  • max_sum:全局最大连续 1 的个数

遍历数组:

  1. 遇到 1pre_sum 加 1(或加 num 本身,因为 1 的值为 1)
  2. 遇到 0
    • max_sum = Math.max(max_sum, pre_sum) 更新全局最大值
    • pre_sum 重置为 0(连续被打断)
  3. 遍历结束后,再次比较 max_sumpre_sum,因为数组可能以 1 结尾而没有遇到 0 来触发更新

举例说明

以输入 nums = [1, 1, 0, 1, 1, 1] 为例:

i num pre_sum max_sum 说明
0 1 1 0 遇到 1,计数增加
1 1 2 0 遇到 1,计数增加
2 0 0 2 遇到 0,更新 max_sum=2,重置 pre_sum
3 1 1 2 遇到 1,计数增加
4 1 2 2 遇到 1,计数增加
5 1 3 2 遇到 1,计数增加
结束 - 3 max(2,3)=3 返回 3

最终结果为 3。

边界情况

  • 全 1 数组:如 [1, 1, 1],没有 0 触发更新,最后的 Math.max 处理了这种情况
  • 全 0 数组:如 [0, 0]pre_sum 始终为 0,max_sum 也为 0
  • 单元素数组:[1] 返回 1,[0] 返回 0

复杂度分析

  • 时间复杂度:O(n),只需遍历数组一次。
  • 空间复杂度:O(1),只使用了两个整数变量。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package code.J485;

public class J485 {
public int findMaxConsecutiveOnes(int[] nums) {
int pre_sum = 0;
int max_sum = 0;
for (int num : nums) {
if (num == 0) {
max_sum = Math.max(max_sum, pre_sum);
pre_sum = 0;
} else {
pre_sum += num;
}
}
return Math.max(max_sum, pre_sum);
}
}