LeetCode-57-插入区间

题目

给你一个 无重叠的 按照区间起始端点排序的区间列表 intervals,其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。

intervals 中插入区间 newInterval,使得 intervals 依然按照 starti 升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。

返回插入之后的 intervals

注意 你不需要原地修改 intervals。你可以创建一个新数组然后返回它。

示例 1:

1
2
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]

示例 2:

1
2
3
输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8][3,5],[6,7],[8,10] 重叠。

提示:

  • 0 <= intervals.length <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 105
  • intervals 根据 starti升序 排列
  • newInterval.length == 2
  • 0 <= start <= end <= 105

题解

这一题其实不算很难,需要静下心来好好分析一下:

一次遍历intervals,当前区间如果为interval,对于每个区间有三种情况:

  • 当前区间在新区间的右侧,也就是newInterval[1] < interval[0],这时如果新区间没有被加入,需要加入新区间然后再加入当前区间;
  • 当前区间在新区间的左侧,即newInterval[1] < interval[0],这个时候把当前区间加入到答案里;
  • 否则,说明新区间和当前区间有交集,我们取当前区间的左端点和新区间左端点的最小值,然后取当前区间的右端点和新区间右端点的最大值,作为新区间的断电,继续遍历。
  • 当遍历完成了,新区间还未被加入,把新区间加入到答案里。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> ans = new ArrayList<>();
int st = newInterval[0], ed = newInterval[1];
boolean insert = false;
for (int[] interval : intervals) {
int s = interval[0], e = interval[1];
if (ed < s) { // 当前区间在新区间的右侧
// 如果未插入,就插入
if (!insert) {
ans.add(new int[] {st, ed});
insert = true; // 新区间插入的标记
}
ans.add(interval);
} else if (e < st) { // 当前区间在新区间的左侧
ans.add(interval);
} else { // 有交集的情况
st = Math.min(st, s);
ed = Math.max(ed, e);
}
}
if (!insert) {
ans.add(new int[] {st, ed});
}
return ans.toArray(new int[ans.size()][]);
}
}

LeetCode-57-插入区间
https://excelius.xyz/leetcode-57-插入区间/
作者
Ther
发布于
2024年7月10日
许可协议