【兩次過】Lintcode 156. 合併區間
阿新 • • 發佈:2019-01-11
給出若干閉合區間,合併所有重疊的部分。
樣例
Given intervals => merged intervals:
[ [
(1, 3), (1, 6),
(2, 6), => (8, 10),
(8, 10), (15, 18)
(15, 18) ]
]
挑戰
O(n log n) 的時間和 O(1) 的額外空間。
解題思路:
先對區間進行排序,按start升序,end降序排列,也就是先讓大區間排前面,當覆蓋掉小區間時方便計算。
然後依次遍歷排序後的區間,分為三種情況:覆蓋、交叉、分離,具體見程式碼。
/** * Definition of Interval: * public classs Interval { * int start, end; * Interval(int start, int end) { * this.start = start; * this.end = end; * } * } */ public class Solution { /** * @param intervals: interval list. * @return: A new interval list. */ public List<Interval> merge(List<Interval> intervals) { // write your code here //按start升序,end降序排列,也就是先讓大區間排前面,當覆蓋掉小區間時方便計算 Collections.sort(intervals, new Comparator<Interval>(){ public int compare(Interval i1, Interval i2){ if(i1.start < i2.start) return -1; else if(i1.start > i2.start) return 1; else{ if(i1.end < i2.end) return 1; else if(i1.end > i2.end) return -1; else return 0; } } }); List<Interval> res = new ArrayList<>(); int start = -1;//儲存上一個區間的start int end = -1;//儲存上一個區間的end for(Interval i : intervals){ //如果上一個區間已經包含了此區間,則跳過此區間 if(start <= i.start && end >= i.end){ continue; } //如果上一個區間與當前區間有交叉,則合併兩區間 else if(i.start <= end){ res.remove(res.size()-1); res.add(new Interval(start, i.end)); end = i.end; //否則直接將其加入結果集中,並重新整理start與end }else{ start = i.start; end = i.end; res.add(i); } } return res; } }