1. 程式人生 > >57. Insert Interval

57. Insert Interval

面試官 urn 條件 his pub got 代碼 result -o

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.

Example 1:
Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9].

Example 2:
Given [1,2
],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16]. This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10].

使用的for 循環惡心死, while 先找插入位置, 再不斷合並中間重復的interval, 最後直接再加上後面的, while 中的條件可以畫圖得到

這道題跟Merge Intervals很類似,都是關於數據結構interval的操作。事實上,Merge Intervals是這道題的子操作,就是插入一個interval,如果出現沖突了,就進行merge。跟Merge Intervals不一樣的是,這道題不需要排序,因為插入之前已經默認這些intervals排好序了。簡單一些的是這裏最多只有一個連續串出現沖突,因為就插入那麽一個。基本思路就是先掃描走到新的interval應該插入的位置,接下來就是插入新的interval並檢查後面是否沖突,一直到新的interval的end小於下一個interval的start,然後取新interval和當前interval中end大的即可。因為要進行一次線性掃描,所以時間復雜度是O(n)。而空間上如果我們重新創建一個ArrayList返回,那麽就是O(n)。有朋友可能會說為什麽不in-place的進行操作,這樣就不需要額外空間,但是如果使用ArrayList這個數據結構,那麽刪除操作是線性的,如此時間就不是O(n)的。如果這道題是用LinkedList那麽是可以做到in-place的,並且時間是線性的。代碼如下:

public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
    List<Interval> result = new LinkedList<>();
    int i = 0;
    // add all the intervals ending before newInterval starts
    while (i < intervals.size() && intervals.get(i).end < newInterval.start)
        result.add(intervals.get(i++));
    // merge all overlapping intervals to one considering newInterval
    while (i < intervals.size() && intervals.get(i).start <= newInterval.end) {
        newInterval = new Interval( // we could mutate newInterval here also
                Math.min(newInterval.start, intervals.get(i).start),
                Math.max(newInterval.end, intervals.get(i).end));
        i++;
    }
    result.add(newInterval); // add the union of intervals we got
    // add all the rest
    while (i < intervals.size()) result.add(intervals.get(i++)); 
    return result;
}

這道題有一個變體,就是如果插入的時候發現沖突,那就返回失敗,不插入了。看起來好像比上面這道題還要簡單,但是要註意的是,如此我們就不需要進行線性掃描了,而是進行二分查找,如果不沖突,則進行插入,否則直接返回失敗。這樣時間復雜度可以降低到O(logn)。當然這裏需要用二分查找樹去維護這些intervals。所以一點點變化可能可以使復雜度降低,還是應該多做思考哈。
同時,這種題目還可以問一些關於OO設計的東西,比如就直接問你要實現一個intervals的類,要維護哪些變量,實現哪些功能,用什麽數據結構,等等。這些你可以跟面試官討論,然後根據他的功能要求用相應的數據結構。所以擴展性還是很強的,大家可以考慮的深入一些。

57. Insert Interval