228. 汇总区间

228. 汇总区间

✨核心逻辑

本题采用 一次遍历(双指针) 的策略:

  1. 有序数组特性:题目给定的数组是无重复元素的有序数组。这意味着如果一段数字是连续的,那么相邻元素必定满足 nums[i] + 1 == nums[i + 1]
  2. 寻找区间:外层循环使用 i 遍历数组,在每一次外层循环中,先固定当前元素为区间的起点 start。然后利用内层 while 循环不断向后移动 i,直到发现断点(即不连续的位置)。
  3. 记录区间:内层循环结束后,此时的 nums[i] 即为区间的终点 end。如果 start == end,说明只有一个元素,直接将其转为字符串加入结果;否则,按照 start + "->" + end 的格式拼接并加入结果。
  4. 更新指针:处理完当前区间后,外层循环的 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循环深入探索,不满足时即为答案