题目
标题和出处
标题:区间列表的交集
出处:986. 区间列表的交集
难度
4 级
题目描述
要求
给定两个由闭区间组成的列表, firstList \texttt{firstList} firstList 和 secondList \texttt{secondList} secondList,其中 firstList[i] = [start i , end i ] \texttt{firstList[i] = [start}_\texttt{i}\texttt{, end}_\texttt{i}\texttt{]} firstList[i] = [starti, endi], secondList[j] = [start j , end j ] \texttt{secondList[j] = [start}_\texttt{j}\texttt{, end}_\texttt{j}\texttt{]} secondList[j] = [startj, endj]。同一个区间列表中的区间各不相交,并且已经排序。
返回这两个区间列表的交集。
闭区间 [a, b] \texttt{[a, b]} [a, b](其中 a ≤ b \texttt{a} \le \texttt{b} a≤b)表示满足 a ≤ x ≤ b \texttt{a} \le \texttt{x} \le \texttt{b} a≤x≤b 的实数 x \texttt{x} x 的集合。
两个闭区间的交集是一组实数,为空集或闭区间。例如, [1, 3] \texttt{[1, 3]} [1, 3] 和 [2, 4] \texttt{[2, 4]} [2, 4] 的交集为 [2, 3] \texttt{[2, 3]} [2, 3]。
示例
示例 1:

输入:
firstList
=
[[0,2],[5,10],[13,23],[24,25]],
secondList
=
[[1,5],[8,12],[15,24],[25,26]]
\texttt{firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]]}
firstList = [[0,2],[5,10],[13,23],[24,25]], secondList = [[1,5],[8,12],[15,24],[25,26]]
输出:
[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]
\texttt{[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]}
[[1,2],[5,5],[8,10],[15,23],[24,24],[25,25]]
示例 2:
输入:
firstList
=
[[1,3],[5,9]],
secondList
=
[]
\texttt{firstList = [[1,3],[5,9]], secondList = []}
firstList = [[1,3],[5,9]], secondList = []
输出:
[]
\texttt{[]}
[]
数据范围
- 0 ≤ firstList.length, secondList.length ≤ 1000 \texttt{0} \le \texttt{firstList.length, secondList.length} \le \texttt{1000} 0≤firstList.length, secondList.length≤1000
- firstList.length + secondList.length ≥ 1 \texttt{firstList.length} + \texttt{secondList.length} \ge \texttt{1} firstList.length+secondList.length≥1
- 0 ≤ start i < end i ≤ 10 9 \texttt{0} \le \texttt{start}_\texttt{i} < \texttt{end}_\texttt{i} \le \texttt{10}^\texttt{9} 0≤starti<endi≤109
- end i < start i + 1 \texttt{end}_\texttt{i} < \texttt{start}_\texttt{i + 1} endi<starti + 1
- 0 ≤ start j < end j ≤ 10 9 \texttt{0} \le \texttt{start}_\texttt{j} < \texttt{end}_\texttt{j} \le \texttt{10}^\texttt{9} 0≤startj<endj≤109
- end j < start j + 1 \texttt{end}_\texttt{j} < \texttt{start}_\texttt{j + 1} endj<startj + 1
解法
思路和算法
由于给定的两个区间列表满足同一个区间列表中的区间各不相交且已经按升序排序,因此不需要处理区间合并,只需要从左到右同时遍历两个区间列表即可计算交集。
使用一个列表存储区间列表的交集。用 index 1 \textit{index}_1 index1 和 index 2 \textit{index}_2 index2 分别表示区间列表 firstList \textit{firstList} firstList 和 secondList \textit{secondList} secondList 的下标,初始时 index 1 = index 2 = 0 \textit{index}_1 = \textit{index}_2 = 0 index1=index2=0。
当 index 1 \textit{index}_1 index1 和 index 2 \textit{index}_2 index2 都未超出区间列表的下标范围时,同时遍历两个区间列表,记 interval 1 = firstList [ index 1 ] \textit{interval}_1 = \textit{firstList}[\textit{index}_1] interval1=firstList[index1], interval 2 = secondList [ index 2 ] \textit{interval}_2 = \textit{secondList}[\textit{index}_2] interval2=secondList[index2],记 start = max ( interval 1 [ 0 ] , interval 2 [ 0 ] ) \textit{start} = \max(\textit{interval}_1[0], \textit{interval}_2[0]) start=max(interval1[0],interval2[0]), end = min ( interval 1 [ 1 ] , interval 2 [ 1 ] ) \textit{end} = \min(\textit{interval}_1[1], \textit{interval}_2[1]) end=min(interval1[1],interval2[1]),执行如下操作。
-
如果 start ≤ end \textit{start} \le \textit{end} start≤end,则当前的两个区间 interval 1 \textit{interval}_1 interval1 和 interval 2 \textit{interval}_2 interval2 的交集为 [ start , end ] [\textit{start}, \textit{end}] [start,end],将 [ start , end ] [\textit{start}, \textit{end}] [start,end] 添加到交集列表中。如果 start > end \textit{start} > \textit{end} start>end,则当前的两个区间 interval 1 \textit{interval}_1 interval1 和 interval 2 \textit{interval}_2 interval2 的交集为空,不添加到交集列表中。
-
比较当前的两个区间 interval 1 \textit{interval}_1 interval1 和 interval 2 \textit{interval}_2 interval2 的末端,即 interval 1 [ 1 ] \textit{interval}_1[1] interval1[1] 和 interval 2 [ 1 ] \textit{interval}_2[1] interval2[1],将末端较小的区间对应的下标向右移动一位。具体做法如下。
-
如果 interval 1 [ 1 ] = interval 2 [ 1 ] \textit{interval}_1[1] = \textit{interval}_2[1] interval1[1]=interval2[1],则 interval 1 \textit{interval}_1 interval1 和 interval 2 \textit{interval}_2 interval2 都不可能和两个区间列表中的其余区间有交集,因此将 index 1 \textit{index}_1 index1 和 index 2 \textit{index}_2 index2 同时向右移动一位。
-
如果 interval 1 [ 1 ] < interval 2 [ 1 ] \textit{interval}_1[1] < \textit{interval}_2[1] interval1[1]<interval2[1],则 interval 1 \textit{interval}_1 interval1 不可能和 secondList \textit{secondList} secondList 中的其余区间有交集,但是 interval 2 \textit{interval}_2 interval2 仍可能和 firstList \textit{firstList} firstList 中的其余区间有交集,因此将 index 1 \textit{index}_1 index1 向右移动一位。
-
如果 interval 1 [ 1 ] > interval 2 [ 1 ] \textit{interval}_1[1] > \textit{interval}_2[1] interval1[1]>interval2[1],则 interval 2 \textit{interval}_2 interval2 不可能和 firstList \textit{firstList} firstList 中的其余区间有交集,但是 interval 1 \textit{interval}_1 interval1 仍可能和 secondList \textit{secondList} secondList 中的其余区间有交集,因此将 index 2 \textit{index}_2 index2 向右移动一位。
-
重复上述操作,直到 index 1 \textit{index}_1 index1 和 index 2 \textit{index}_2 index2 当中至少有一个下标超出区间列表的下标范围。如果一个下标超出区间列表的下标范围,则该下标所在的区间列表中的所有区间都已经被遍历过,因此不可能有更多的非空交集,此时得到完整的交集。
遍历结束之后,将列表转成数组返回。
代码
class Solution {
public int[][] intervalIntersection(int[][] firstList, int[][] secondList) {
List<int[]> intersectionList = new ArrayList<int[]>();
int length1 = firstList.length, length2 = secondList.length;
int index1 = 0, index2 = 0;
while (index1 < length1 && index2 < length2) {
int[] interval1 = firstList[index1];
int[] interval2 = secondList[index2];
int start = Math.max(interval1[0], interval2[0]);
int end = Math.min(interval1[1], interval2[1]);
if (start <= end) {
intersectionList.add(new int[]{start, end});
}
if (interval1[1] <= interval2[1]) {
index1++;
}
if (interval1[1] >= interval2[1]) {
index2++;
}
}
return intersectionList.toArray(new int[intersectionList.size()][]);
}
}
复杂度分析
-
时间复杂度: O ( m + n ) O(m + n) O(m+n),其中 m m m 和 n n n 分别是区间列表 firstList \textit{firstList} firstList 和 secondList \textit{secondList} secondList 的长度。双指针遍历两个区间列表各一次。
-
空间复杂度: O ( m + n ) O(m + n) O(m+n),其中 m m m 和 n n n 分别是区间列表 firstList \textit{firstList} firstList 和 secondList \textit{secondList} secondList 的长度。存储区间交集的列表需要 O ( m + n ) O(m + n) O(m+n) 的空间。

4090

被折叠的 条评论
为什么被折叠?



