问题
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。
请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].示例 2:
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
思路
合并重叠区间的问题可以通过排序和遍历的方法来解决。以下是解决这个问题的步骤:1、排序:首先,根据区间的起始点对区间进行排序。
2、初始化:创建一个新的列表 merged 来存储合并后的区间,初始化时可以添加排序后的第一个区间。
3、遍历:遍历排序后的区间列表,对于每个区间,检查它是否与 merged 列表中的最后一个区间重叠。如果重叠,将两个区间合并;如果不重叠,将当前区间添加到 merged 列表中。
4、合并逻辑:如果当前区间的起始点小于或等于 merged 列表中最后一个区间的结束点,则合并这两个区间,即将 merged 列表中最后一个区间的结束点更新为当前区间的结束点和 merged 列表中最后一个区间的结束点的较大值。
当然可以。让我们通过一个具体的例子和图形来解释合并重叠区间的算法。假设我们有以下区间集合:```
intervals = [[1, 3], [2, 6], [8, 10], [15, 18]]
```### 步骤 1: 排序
首先,我们根据区间的起始点对区间进行排序。排序后的区间如下:```
sorted_intervals = [[1, 3], [2, 6], [8, 10], [15, 18]]
```### 步骤 2: 初始化
我们初始化一个空列表 `merged` 来存储合并后的区间,并添加排序后的第一个区间:```
merged = [[1, 3]]
```### 步骤 3: 遍历并合并
接下来,我们遍历排序后的区间列表,从第二个区间开始,尝试与 `merged` 列表中的最后一个区间合并。#### 合并第一个区间
第二个区间 `[2, 6]` 与 `merged` 中的最后一个区间 `[1, 3]` 重叠(因为 `2 <= 3`)。我们合并这两个区间,合并后的区间为 `[1, 6]`,并更新 `merged` 列表:```
merged = [[1, 6]]
```#### 合并第二个区间
第三个区间 `[8, 10]` 与 `merged` 中的最后一个区间 `[1, 6]` 不重叠(因为 `8 > 6`)。我们直接将这个区间添加到 `merged` 列表中:```
merged = [[1, 6], [8, 10]]
```#### 合并第三个区间
第四个区间 `[15, 18]` 与 `merged` 中的最后一个区间 `[8, 10]` 不重叠(因为 `15 > 10`)。我们直接将这个区间添加到 `merged` 列表中:```
merged = [[1, 6], [8, 10], [15, 18]]
```### 最终结果
经过上述步骤,我们得到了合并所有重叠区间后的不重叠区间数组:```
[[1, 6], [8, 10], [15, 18]]
```### 图形解释
下面是每个步骤的图形表示:1. **初始状态**:```[1, 3] [2, 6] [8, 10] [15, 18]```2. **合并第一个区间**:```[1, 6] [8, 10] [15, 18]```3. **合并第二个区间**:```[1, 6] [8, 10] [15, 18]```4. **合并第三个区间**:```[1, 6] [8, 10] [15, 18]```通过这种方式,我们可以看到每个区间如何被合并,以及最终如何得到一个不重叠的区间数组,该数组覆盖了所有原始区间。
解法
class Solution:def merge(self, intervals: list[list[int]]) -> list[list[int]]:if not intervals or len(intervals) <= 1:return intervalsintervals.sort(key =lambda x : x[0])merged = [intervals[0]]for current in intervals[1:]:last = merged[-1]if current[0] <= last[1]:last[1] = max(last[1], current[1])else:merged.append(current)return merged
学习
if not intervals or len(intervals) <= 1: 这行代码是一个条件语句,用于检查 intervals 列表的特定条件。让我们分解这个条件语句来理解它的含义:intervals:这是一个变量,通常是一个列表,包含了一系列的区间,每个区间由一个包含两个元素的列表表示,如 [[start, end]]。not intervals:这部分检查 intervals 是否为 False。在Python中,空列表 [] 被视为 False。所以,如果 intervals 是空列表,not intervals 将为 True。len(intervals) <= 1:这部分检查 intervals 列表的长度是否小于或等于1。如果列表中元素的数量不超过1,即列表为空或只包含一个元素,这个条件为 True。or:这是一个逻辑运算符,用于连接两个条件。如果任一条件为 True,则整个表达式的结果为 True。综合来看,if not intervals or len(intervals) <= 1: 这个条件语句的意思是:如果 intervals 是空列表(即没有区间),或者
如果 intervals 只包含一个区间或没有区间,
那么这个条件语句为真。在这种情况下,通常不需要进一步处理,因为合并区间的逻辑主要适用于至少有两个区间的情况。如果只有一个或没有区间,可以直接返回原始列表,因为没有重叠的区间需要合并。在合并区间的算法中,这个条件通常用于快速返回,避免不必要的计算。例如,如果列表为空或只有一个区间,就直接返回这个列表,因为不需要合并。
`intervals.sort(key=lambda x: x[0])` 这行代码是对列表 `intervals` 进行原地(in-place)排序的语句。这里的 `sort` 方法会对列表中的元素按照指定的关键字进行排序。让我们分解这行代码来更好地理解它:1. `intervals`:这是需要排序的列表,其中每个元素都是一个表示区间的列表 `[start, end]`。2. `sort`:这是Python列表的一个方法,用于对列表中的元素进行排序。默认情况下,`sort` 方法会按照元素的自然顺序进行排序,对于数字来说是从小到大,对于字符串来说是按照字母顺序。3. `key`:这是`sort`方法的一个可选参数,它接受一个函数作为参数。这个函数会在每个元素上调用,`sort`方法会根据这个函数返回的结果来决定元素的排序顺序。4. `lambda x: x[0]`:这是一个匿名函数,也称为lambda函数。它接受一个参数 `x`(在这里,`x` 是 `intervals` 列表中的每个区间),并返回 `x[0]`,即每个区间的起始点。这个lambda函数作为 `key` 参数的值,意味着排序将基于区间的起始点进行。综上所述,`intervals.sort(key=lambda x: x[0])` 这行代码的作用是将 `intervals` 列表中的区间按照它们的起始点进行升序排序。这样,排序后的列表中,每个区间的起始点都会小于或等于它后面区间的起始点,这为后续合并重叠区间的步骤提供了便利。