228. 汇总区间
✨核心逻辑
本题采用 一次遍历(双指针) 的策略:
- 有序数组特性:题目给定的数组是无重复元素的有序数组。这意味着如果一段数字是连续的,那么相邻元素必定满足
nums[i] + 1 == nums[i + 1]。 - 寻找区间:外层循环使用
i遍历数组,在每一次外层循环中,先固定当前元素为区间的起点start。然后利用内层while循环不断向后移动i,直到发现断点(即不连续的位置)。 - 记录区间:内层循环结束后,此时的
nums[i]即为区间的终点end。如果start == end,说明只有一个元素,直接将其转为字符串加入结果;否则,按照start + "->" + end的格式拼接并加入结果。 - 更新指针:处理完当前区间后,外层循环的
i需要自增,指向下一个尚未处理的新区间的起点。
🔥代码实现(含详细变量注释)
class Solution {
public List<String> summaryRanges(int[] nums) {
// list:用于存放最终生成的各个区间字符串的结果列表
List<String> list = new ArrayList<>();
// n:记录给定数组的长度
int n = nums.length;
// i:主遍历指针,用于在数组中定位连续的区间
int i = 0;
// 只要指针没有超出数组范围,就继续寻找下一个区间
while (i < n) {
// start:记录当前找到的连续区间的起始数字
int start = nums[i];
// 核心判断:只要下一个元素存在,且等于当前元素加 1,说明还在连续区间内
while (i + 1 < n && nums[i + 1] == nums[i] + 1) {
i++; // 指针向右滑动,继续探测区间终点
}
// 内层循环结束时,i 停留在当前连续区间的最后一个元素处
// end:记录当前找到的连续区间的结束数字
int end = nums[i];
// 根据区间首尾是否相等,决定格式化方式
if (start == end) {
// 如果首尾相等,说明区间只有一个数字,直接将其转为字符串
list.add(String.valueOf(start));
} else {
// 如果首尾不等,说明是范围区间,拼接成 "start->end" 的格式
list.add(start + "->" + end);
}
// 处理完当前区间后,i 自增 1,指向下一个可能的新区间的起点
i++;
}
// 返回最终汇总好的区间列表
return list;
}
}
- ⏱️复杂度分析
时间复杂度:O(N),其中 N 是数组的长度。外层 while 循环和内层 while 循环共同控制了遍历进度,数组中的每一个元素恰好会被访问一次,整体操作次数与元素总数成正比。
空间复杂度:O(1)(不考虑返回结果 list 占用的空间)。我们只使用了 n、i、start、end 等常数个额外的整型变量。
🔍总结一下:
定位当前元素,使用while循环深入探索,不满足时即为答案