Insert Interval

  1. 题目
  2. 分析
  3. 实现

题目

插入区间

给出一个无重叠的 ,按照区间起始端点排序的区间列表。

在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)

示例:

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

输入: 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] 重叠

分析

我开始时的错误思路是这样的:遍历所有的旧interval,在能够进行合并时就把旧interval合并到新interval中,否则直接插入到新vector中;最后把更新过的interval插入到新vector中。这种做法显然有一个问题:如果新interval不需要和旧interval合并,那这种算法就找不到正确的插入位置了。

比较好的做法是这样的:遍历所有旧interval,首先将所有严格位于新interval左侧的旧interval保存下来(当然,可能没有这样的interval);然后将与新interval重叠的旧interval进行适当的合并,合并结束的时候,将新interval保存下来;最后将所有严格位于合并后的新interval右侧的旧interval保存下来(当然,也可能没有这样的interval)。

实现

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
bool isOverlap(Interval i1, Interval i2) {
return !(i1.end < i2.start || i2.end < i1.start);
}

Interval merge(Interval i1, Interval i2) {
return Interval(min(i1.start, i2.start), max(i1.end, i2.end));
}

public:
vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
// 现在的想法是,维护这个newInterval,然后遍历所有的旧interval,发现重叠时就更新newInterval,直到完全不重叠为止
// 需要证明的是,即使因为overlap更新了当前的interval,这并不会影响到之前的interval
// 没有考虑到如何找到正确插入位置的问题。
vector<Interval> ans;
int finished = -1;
for (Interval interval: intervals) {
if (!isOverlap(interval, newInterval)) {
if (finished == 0) {
ans.push_back(newInterval);
finished = 1;
}
ans.push_back(interval);
}
else {
if (finished == -1)
finished = 0;
newInterval = merge(newInterval, interval);
}
}
// 找到正确的插入位置
if (finished != 1) {
for (int i = 0; i < ans.size(); i++) {
if (ans[i].start > newInterval.end) {
ans.insert(ans.begin() + i, newInterval);
finished = 1;
break;
}
}
if (finished != 1)
ans.push_back(newInterval);
}
return ans;
}
};

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 yxhlfx@163.com

文章标题:Insert Interval

本文作者:红尘追风

发布时间:2015-04-18, 11:06:12

原始链接:http://www.micernel.com/2015/04/18/InsertInterval/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录