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"算法步骤
- 令
i = 0,初始化结果列表res。 - 当
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。
- 记段起点
- 返回
res。
逐步举例
以 nums = [0,2,3,4,6,8,9] 为例:
| 段起点 i | 段终点 j | nums | 输出 |
|---|---|---|---|
| 0 | 0 | [0] | “0” |
| 1 | 3 | [2,3,4] | “2->4” |
| 4 | 4 | [6] | “6” |
| 5 | 6 | [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 resimport sysfrom 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 %}}