Insert Interval
    
    
    
        
    
    
        
        
        
    
    
    
    
    
      
        题目
插入区间
给出一个无重叠的 ,按照区间起始端点排序的区间列表。
在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)
示例:
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" 转载请保留原文链接及作者。