給定一組無重疊且按起始點升序排列的區間集合,插入一個新區間,必要時合併重疊區間,返回新的區間列表。
範例 1:intervals = [[1,3],[6,9]], newInterval = [2,5] → [[1,5],[6,9]]
範例 2:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,9] → [[1,2],[3,10],[12,16]]
利用「合併區間」的經典邏輯:將新區間加入列表,重新排序,然後單次掃描合併。雖然排序帶來 O(n log n) 複雜度,但代碼極其簡潔,且對於 n ≤ 10^4 完全足夠。若要求 O(n),可利用原列表已有序特性,三段式處理(左不重疊、中間合併、右不重疊)。
class Solution {
public List insert(List intervals, Interval newInterval) {
intervals.add(newInterval);
return merge(intervals);
}
private List merge(List intervals) {
if (intervals == null || intervals.size() <= 1) return intervals;
intervals.sort(Comparator.comparingInt(i -> i.start));
List res = new ArrayList<>();
Interval prev = intervals.get(0);
for (int i = 1; i < intervals.size(); ++i) {
Interval cur = intervals.get(i);
if (prev.end >= cur.start) { // 重疊
prev = new Interval(prev.start, Math.max(prev.end, cur.end));
} else {
res.add(prev);
prev = cur;
}
}
res.add(prev);
return res;
}
}
方法 時間 空間 備註 排序法 O(n log n) O(n) 代碼簡短,通用性強 三段式 O(n) O(n) 利用有序特性,面試加分項