483 字
2 分钟
228. 汇总区间

228. 汇总区间#

题目描述#

给定一个无重复元素的有序整数数组 nums。

返回恰好覆盖数组中所有数字的最小有序区间范围列表。也就是说,nums 的每个元素都恰好被某个区间范围所覆盖,并且不存在属于某个范围但不属于 nums 的数字 x。

列表中的每个区间范围 [a,b] 应该按如下格式输出:

  • "a->b",如果 a != b;
  • "a",如果 a == b。

示例 1:

输入:nums = [0,1,2,4,5,7]
输出:["0->2","4->5","7"]
解释:区间范围是:
[0,2] --> "0->2"
[4,5] --> "4->5"
[7,7] --> "7"

示例 2:

输入:nums = [0,2,3,4,6,8,9]
输出:["0","2->4","6","8->9"]

提示:

  • 0 <= nums.length <= 20
  • -2^31 <= nums[i] <= 2^31 - 1

解题思路#

核心思想#

用分组循环把数组切成若干段「连续整数」区间:段内相邻元素差恒为 1。对每个段 [i, j],若 nums[i] == nums[j] 则输出单个 "x",否则输出 "x"->"y"。

分组示意(nums = [0,1,2,4,5,7]):

[0,1,2] / [4,5] / [7] → "0->2" / "4->5" / "7"

算法步骤#

  1. 令 i = 0,初始化结果列表 res。
  2. 当 i < n 时:
    • 记段起点 start = nums[i];
    • j = i,内层 while j+1 < n and nums[j+1] == nums[j] + 1 时 j++;
    • 若 start == nums[j],追加 str(start);否则追加 f"{start}->{nums[j]}";
    • i = j + 1。
  3. 返回 res。

逐步举例#

以 nums = [0,2,3,4,6,8,9] 为例:

段起点 i段终点 jnums输出
00[0]“0”
13[2,3,4]“2->4”
44[6]“6”
56[8,9]“8->9”

结果为 ["0","2->4","6","8->9"]。

复杂度分析#

  • 时间复杂度:O(N),单次线性扫描。
  • 空间复杂度:O(1)(不计输出结果空间)。

代码实现#

{{% highlight python %}}

from typing import List
class Solution:
def summaryRanges(self, nums: List[int]) -> List[str]:
res = []
n = len(nums)
i = 0
while i < n:
start = nums[i]
j = i
while j + 1 < n and nums[j + 1] == nums[j] + 1:
j += 1
if start == nums[j]:
res.append(str(start))
else:
res.append(f"{start}->{nums[j]}")
i = j + 1
return res
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
import unittest
from solution import Solution
class TestSolution(unittest.TestCase):
def test_example1(self):
self.assertEqual(Solution().summaryRanges([0, 1, 2, 4, 5, 7]),
["0->2", "4->5", "7"])
def test_example2(self):
self.assertEqual(Solution().summaryRanges([0, 2, 3, 4, 6, 8, 9]),
["0", "2->4", "6", "8->9"])
if __name__ == '__main__':
unittest.main()

{{% /highlight %}}

228. 汇总区间
https://h1s97x.github.io/posts/coding/coding-228-summary-ranges/
作者
H1S97X
发布于
2026-08-23
许可协议
CC BY-NC-SA 4.0
随机文章