1. 程式人生 > >56. Merge Intervals

56. Merge Intervals

ret start public 大於等於 while ref init poll() list

Given a collection of intervals, merge all overlapping intervals.

For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].

這道題跟Insert Intervals這道題很像,最開頭要先對Intervals裏面的Interval排序一下,用到了java的Collections.sort(List<Interval> list, Comparator<? super Interval> c)。 排序以Interval的start為第一標準,從小到大,如果start一樣的情況下,才以end作為第二標準。這樣排序的好處是,簡化了接下來處理的難度。

我們只需要把intervals裏的interval依次添加到結果集合裏,每次將要添加時,只需要判斷當前這個interval的start跟結果集合裏面最後一個Interval的end誰大,如果結果集合裏面最後一個Interval的end大,說明overlap了,需要改一下這個end就好了,否則沒有Overlap,直接添加該Interval進結果集合裏就好了。

sort的好處是,只用管end,不用管start, 因為新添加的Interval的start至少是大於等於結果集合裏面已經添加的Interval的start的。換言之,start不受影響,簡化了我們的處理。

所以本問題的關鍵在於給Intervals排序,可以用java的Collections.sort(List<Interval> list, Comparator<? super Interval> c)。因為Interval是我們自己定義的,所以我們也需要自己定義Comparator,而不能用默認的。我們可以寫一個我們自己的Comparator來override默認的。規則是按起始點排序,然後如果起始點相同就按結束點排序。整個算法是先排序,然後再做一次線性遍歷,時間復雜度是O(nlogn+n)=O(nlogn),空間復雜度是O(1),因為不需要額外空間,只有結果集的空間。

/**
 * 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> merge(List<Interval> intervals) {
        ArrayList<Interval> res = new ArrayList<Interval>();
        if (intervals == null || intervals.size() == 0) {
            return intervals;
        }
        Comparator<Interval> comp = new Comparator<Interval>() {
            public int compare(Interval t1, Interval t2) {
                if (t1.start == t2.start) {
                    return t1.end - t2.end;
                }
                return t1.start - t2.start;
            }
        };
        Collections.sort(intervals, comp);
        res.add(intervals.get(0));
        for (int i=1; i<intervals.size(); i++) {
            if (res.get(res.size()-1).end >= intervals.get(i).start) {
                res.get(res.size()-1).end = Math.max(res.get(res.size()-1).end, intervals.get(i).end);
            }
            else {
                res.add(intervals.get(i));
            }
        }
        return res;
    }
}

  

第一次做, 不能一股腦的用heap 啊

/**
 * 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> merge(List<Interval> intervals) {
        List<Interval> ans = new ArrayList<>();
        if (intervals == null || intervals.size() == 0) {
            return ans;
        }
        Comparator<Interval> comp = new Comparator<Interval>(){
            public int compare(Interval a, Interval b) {
                return a.start == b.start ? a.end - b.end : a.start - b.start;
            }
        };
        Comparator<Interval> cmp = new Comparator<Interval>(){
            public int compare(Interval a, Interval b) {
                return b.end - a.end;
            }
        };
        Collections.sort(intervals, comp);
        PriorityQueue<Interval> heap = new PriorityQueue<>(cmp);
        heap.add(intervals.get(0));
        for (int i = 1; i < intervals.size(); i++) {
            if (heap.peek().end >= intervals.get(i).start) {
                Interval cur = heap.poll();
                Interval merge = new  Interval(cur.start, Math.max(cur.end, intervals.get(i).end));
                heap.add(merge);
            } else {
                heap.add(intervals.get(i));
            }
            
        }
        while (!heap.isEmpty()) {
            ans.add(heap.poll());
        }
        return ans;        
    }
}

  

56. Merge Intervals