一、題目描述
Given a collection of intervals, merge all overlapping intervals.
Input: [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
二、題解
方法一:貪心
錯誤思想:本來我想直接用 end 記錄第 i 輪循環前 i-1 個區間中的最大結束位置的值,然後用它來決定是否合併區間:
- 如果不重合,直接 add 當前數組,跟新 end 值與 endi 下標。
- 否則,讓 list 中最後一個元素的右端點置爲
max(end, inte[i][0])
但這樣做有一個問題:當出現這種破玩意兒的時候,就炸了…[[1,4],[0,5]]
public int[][] merge(int[][] inte) {
if (inte.length <= 1) {
return inte;
}
List<int[]> list = new LinkedList<>();
int end = inte[0][1], endi = 0;
Arrays.sort(inte, (e1, e2) -> e1[0] - e2[0]);
list.add(inte[0]);
for (int i = 1; i < inte.length; i++) {
if (end < inte[i][0]) { //無交集
list.add(inte[i]);
end = inte[i][1];
endi = i;
} else if (end >= inte[i][0]){//交集
list.get(endi)[1] = Math.max(inte[i][1], end);
}
}
int[][] res = new int[list.size()][2];
int i = 0;
for (int[] arr : list) {
res[i++] = arr;
}
return res;
}
想了想,還是直接在鏈表上判斷省事一點把。
public int[][] merge(int[][] inte) {
if (inte.length == 1) {
return inte;
}
List<int[]> list = new ArrayList<>();
Arrays.sort(inte, (e1, e2) -> e1[0] - e2[0]);
for (int i = 0; i < inte.length; i++) {
if (list.isEmpty() || list.get(list.size()-1)[1] < inte[i][0]) {
list.add(inte[i]);
} else {
int end = list.get(list.size()-1)[1];
list.get(list.size()-1)[1] = Math.max(end, inte[i][1]);
}
}
int[][] res = new int[list.size()][2];
int i = 0;
for (int[] arr : list) {
res[i++] = arr;
}
return res;
}
複雜度分析
- 時間複雜度:,
- 空間複雜度:,