LC57. Insert Interval

Insert interval with merge

Posted by freeCookie🍪 on December 21, 2016

Insert Interval

Question

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times.

Analysis

When a new interval in inserted into the existed intervals, when the existed intervals’ end less than the new’s start or start larger than new’s end, no need to processing. Else merge them. This can be done by binary search and inplace.

Code

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
       // when existed intervals'end < new interval's start, do not change anything
       // else merge intervals until existed intervals' start > new intervals' end
       // using binary search, inplace 
       // What is the time cost of ArrayList API in java???
       if(intervals == null || intervals.size() == 0) {
           intervals = new ArrayList<Interval>();
           intervals.add(newInterval);
           return intervals;
       } 
       int low = 0, high = intervals.size()-1, mid = 0;
       // if margin, well this is a right answer 
       /*
       if(intervals.get(low).start > newInterval.end){
           intervals.add(0, newInterval);
           return intervals;
       }else if(intervals.get(high).end < newInterval.start){
           intervals.add(newInterval);
           return intervals;
       } 
       */
       // find the insert place
       while(low <= high){
           mid = low + (high - low)/2;
           Interval cur = intervals.get(mid);
           if(cur.end == newInterval.start)   break;
           else if(cur.end < newInterval.start){
               low = mid + 1;
           }else{
               high = mid - 1;
           }
       } // while
       int insert = (low == high?low:mid);
       // corner case
       if(intervals.get(insert).end < newInterval.start && insert != intervals.size()-1)   insert++;
       high = intervals.size()-1;
       low = insert;
       // find the end of merge
       while(low <= high){
           mid = low + (high - low)/2;
           Interval cur = intervals.get(mid);
           if(cur.start == newInterval.end) break;
           else if(cur.start > newInterval.end){
               high = mid - 1;
           }else{
               low = mid + 1;
           }
       } // while
       int endinsert = (low == high?low:mid);
       // corner case
       if(intervals.get(endinsert).start > newInterval.end && endinsert != 0)   endinsert--;
       // corner case
       if(insert == endinsert){
           if(intervals.get(insert).end < newInterval.start){
               intervals.add(newInterval);
               return intervals;
           }else if(intervals.get(insert).start > newInterval.end){
               intervals.add(0, newInterval);
               return intervals;
           }
       }
       int b = Math.min(intervals.get(insert).start, newInterval.start);
       int e = Math.max(intervals.get(endinsert).end, newInterval.end);
       /*  by changeing this the time will decrease by 10s
       for(int i = insert; i <= endinsert; i++)
                intervals.remove(insert);
        */
       intervals.subList(insert, endinsert+1).clear();
       intervals.add(insert, new Interval(b, e));
       return intervals;
    }
}

Complexity:

Time: O(nlogn) Space: O(1)

….这个题 如果不要用binary search的话并不要这么多代码… ? 将remove换成clear也会节省20s左右:)。这样时间就比较好了。好气 insert和endinsert表示merge的部分,要考虑最后和最初是insert/endinsert的边界情况。

顺便查一下java ArrayList的时间消耗 顺便又查了查其他的

Java Collections