题目描述
给你一个 无重叠的 ,按照区间起始端点排序的区间列表 intervals
,其中 intervals[i] = [starti, endi]
表示第 i
个区间的开始和结束,并且 intervals
按照 starti
升序排列。同样给定一个区间 newInterval = [start, end]
表示另一个区间的开始和结束。
在 intervals
中插入区间 newInterval
,使得 intervals
依然按照 starti
升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。
返回插入之后的 intervals
。
注意 你不需要原地修改 intervals
。你可以创建一个新数组然后返回它。
示例 1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]
示例 2:
输入: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
解法
方法一:排序 + 区间合并
我们可以先将新区间 newInterval
加入到区间列表 intervals
中,然后按照区间合并的常规方法进行合并。
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是区间的数量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | class Solution:
def insert(
self, intervals: List[List[int]], newInterval: List[int]
) -> List[List[int]]:
def merge(intervals: List[List[int]]) -> List[List[int]]:
intervals.sort()
ans = [intervals[0]]
for s, e in intervals[1:]:
if ans[-1][1] < s:
ans.append([s, e])
else:
ans[-1][1] = max(ans[-1][1], e)
return ans
intervals.append(newInterval)
return merge(intervals)
|
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 | class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
int[][] newIntervals = new int[intervals.length + 1][2];
for (int i = 0; i < intervals.length; ++i) {
newIntervals[i] = intervals[i];
}
newIntervals[intervals.length] = newInterval;
return merge(newIntervals);
}
private int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
List<int[]> ans = new ArrayList<>();
ans.add(intervals[0]);
for (int i = 1; i < intervals.length; ++i) {
int s = intervals[i][0], e = intervals[i][1];
if (ans.get(ans.size() - 1)[1] < s) {
ans.add(intervals[i]);
} else {
ans.get(ans.size() - 1)[1] = Math.max(ans.get(ans.size() - 1)[1], e);
}
}
return ans.toArray(new int[ans.size()][]);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
intervals.emplace_back(newInterval);
return merge(intervals);
}
vector<vector<int>> merge(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end());
vector<vector<int>> ans;
ans.emplace_back(intervals[0]);
for (int i = 1; i < intervals.size(); ++i) {
if (ans.back()[1] < intervals[i][0]) {
ans.emplace_back(intervals[i]);
} else {
ans.back()[1] = max(ans.back()[1], intervals[i][1]);
}
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 | func insert(intervals [][]int, newInterval []int) [][]int {
merge := func(intervals [][]int) (ans [][]int) {
sort.Slice(intervals, func(i, j int) bool { return intervals[i][0] < intervals[j][0] })
ans = append(ans, intervals[0])
for _, e := range intervals[1:] {
if ans[len(ans)-1][1] < e[0] {
ans = append(ans, e)
} else {
ans[len(ans)-1][1] = max(ans[len(ans)-1][1], e[1])
}
}
return
}
intervals = append(intervals, newInterval)
return merge(intervals)
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | function insert(intervals: number[][], newInterval: number[]): number[][] {
const merge = (intervals: number[][]): number[][] => {
intervals.sort((a, b) => a[0] - b[0]);
const ans: number[][] = [intervals[0]];
for (let i = 1; i < intervals.length; ++i) {
if (ans.at(-1)[1] < intervals[i][0]) {
ans.push(intervals[i]);
} else {
ans.at(-1)[1] = Math.max(ans.at(-1)[1], intervals[i][1]);
}
}
return ans;
};
intervals.push(newInterval);
return merge(intervals);
}
|
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 | impl Solution {
pub fn insert(intervals: Vec<Vec<i32>>, new_interval: Vec<i32>) -> Vec<Vec<i32>> {
let mut merged_intervals = intervals.clone();
merged_intervals.push(vec![new_interval[0], new_interval[1]]);
// sort by elem[0]
merged_intervals.sort_by_key(|elem| elem[0]);
// merge interval
let mut result = vec![];
for interval in merged_intervals {
if result.is_empty() {
result.push(interval);
continue;
}
let last_elem = result.last_mut().unwrap();
if interval[0] > last_elem[1] {
result.push(interval);
} else {
last_elem[1] = last_elem[1].max(interval[1]);
}
}
result
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | public class Solution {
public int[][] Insert(int[][] intervals, int[] newInterval) {
int[][] newIntervals = new int[intervals.Length + 1][];
for (int i = 0; i < intervals.Length; ++i) {
newIntervals[i] = intervals[i];
}
newIntervals[intervals.Length] = newInterval;
return Merge(newIntervals);
}
public int[][] Merge(int[][] intervals) {
intervals = intervals.OrderBy(a => a[0]).ToArray();
var ans = new List<int[]>();
ans.Add(intervals[0]);
for (int i = 1; i < intervals.Length; ++i) {
if (ans[ans.Count - 1][1] < intervals[i][0]) {
ans.Add(intervals[i]);
} else {
ans[ans.Count - 1][1] = Math.Max(ans[ans.Count - 1][1], intervals[i][1]);
}
}
return ans.ToArray();
}
}
|
方法二:一次遍历
我们可以遍历区间列表 intervals
,记当前区间为 interval
,对于每个区间有三种情况:
- 当前区间在新区间的右侧,即 $newInterval[1] \lt interval[0]$,此时如果新区间还没有被加入,那么将新区间加入到答案中,然后将当前区间加入到答案中。
- 当前区间在新区间的左侧,即 $interval[1] \lt newInterval[0]$,此时将当前区间加入到答案中。
- 否则,说明当前区间与新区间有交集,我们取当前区间的左端点和新区间的左端点的最小值,以及当前区间的右端点和新区间的右端点的最大值,作为新区间的左右端点,然后继续遍历区间列表。
遍历结束,如果新区间还没有被加入,那么将新区间加入到答案中。
时间复杂度 $O(n)$,其中 $n$ 是区间的数量。忽略答案数组的空间消耗,空间复杂度 $O(1)$。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 | class Solution:
def insert(
self, intervals: List[List[int]], newInterval: List[int]
) -> List[List[int]]:
st, ed = newInterval
ans = []
insert = False
for s, e in intervals:
if ed < s:
if not insert:
ans.append([st, ed])
insert = True
ans.append([s, e])
elif e < st:
ans.append([s, e])
else:
st = min(st, s)
ed = max(ed, e)
if not insert:
ans.append([st, ed])
return ans
|
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 | 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()][]);
}
}
|
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:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> ans;
int st = newInterval[0], ed = newInterval[1];
bool insert = false;
for (auto& interval : intervals) {
int s = interval[0], e = interval[1];
if (ed < s) {
if (!insert) {
ans.push_back({st, ed});
insert = true;
}
ans.push_back(interval);
} else if (e < st) {
ans.push_back(interval);
} else {
st = min(st, s);
ed = max(ed, e);
}
}
if (!insert) {
ans.push_back({st, ed});
}
return ans;
}
};
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | func insert(intervals [][]int, newInterval []int) (ans [][]int) {
st, ed := newInterval[0], newInterval[1]
insert := false
for _, interval := range intervals {
s, e := interval[0], interval[1]
if ed < s {
if !insert {
ans = append(ans, []int{st, ed})
insert = true
}
ans = append(ans, interval)
} else if e < st {
ans = append(ans, interval)
} else {
st = min(st, s)
ed = max(ed, e)
}
}
if !insert {
ans = append(ans, []int{st, ed})
}
return
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 | function insert(intervals: number[][], newInterval: number[]): number[][] {
let [st, ed] = newInterval;
const ans: number[][] = [];
let insert = false;
for (const [s, e] of intervals) {
if (ed < s) {
if (!insert) {
ans.push([st, ed]);
insert = true;
}
ans.push([s, e]);
} else if (e < st) {
ans.push([s, e]);
} else {
st = Math.min(st, s);
ed = Math.max(ed, e);
}
}
if (!insert) {
ans.push([st, ed]);
}
return ans;
}
|
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
28 | impl Solution {
pub fn insert(intervals: Vec<Vec<i32>>, new_interval: Vec<i32>) -> Vec<Vec<i32>> {
let mut inserted = false;
let mut result = vec![];
let (mut start, mut end) = (new_interval[0], new_interval[1]);
for iter in intervals.iter() {
let (cur_st, cur_ed) = (iter[0], iter[1]);
if cur_ed < start {
result.push(vec![cur_st, cur_ed]);
} else if cur_st > end {
if !inserted {
inserted = true;
result.push(vec![start, end]);
}
result.push(vec![cur_st, cur_ed]);
} else {
start = std::cmp::min(start, cur_st);
end = std::cmp::max(end, cur_ed);
}
}
if !inserted {
result.push(vec![start, end]);
}
result
}
}
|
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 | public class Solution {
public int[][] Insert(int[][] intervals, int[] newInterval) {
var ans = new List<int[]>();
int st = newInterval[0], ed = newInterval[1];
bool insert = false;
foreach (var interval in 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 (st > e) {
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();
}
}
|