LeetCode435. 無重疊區間
阿新 • • 發佈:2021-01-17
技術標籤:LeetCode
- 題目描述
給定一個區間的集合,找到需要移除區間的最小數量,使剩餘區間互不重疊。
注意
- 可以認為區間的終點總是大於它的起點。
- 區間 [1,2] 和 [2,3] 的邊界相互“接觸”,但沒有相互重疊。
- 示例
輸入: [ [1,2], [2,3], [3,4], [1,3] ]
輸出: 1
解釋: 移除 [1,3] 後,剩下的區間沒有重疊
輸入: [ [1,2], [1,2], [1,2] ]
輸出: 2
解釋: 你需要移除兩個 [1,2] 來使剩下的區間沒有重疊
輸入: [ [1,2], [2,3] ] 輸出: 0 解釋: 你不需要移除任何區間,因為它們已經是無重疊的了
- 分析 – 貪心演算法
貪心策略:優先保留結尾小且不相交的區
間
把區間按照結尾的大小進行增序排序,每次選擇結尾最小且和前一個選
擇的區間不重疊的區間
- Code
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length < 2 ) {
return 0;
}
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
int res = 0;
int[] pre = intervals[0];
for (int i=1; i<intervals.length; i++) {
int[] cur = intervals[i];
if (cur[0] < pre[1]) {
res++ ;
} else {
pre = cur;
}
}
return res;
}
}
貪心策略:保留最小的區間
先按區間頭從小到大排序,再按照區間尾從小到大排序,保證區間的有序性
選擇不重疊的區間且最小
- Code
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length < 2 ) {
return 0;
}
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return (o1[0] == o2[0]) ? (o1[1] - o2[1]) : (o1[0] - o2[0]);
}
});
int res = 0;
int[] pre = intervals[0];
for (int i=1; i<intervals.length; i++) {
int[] cur = intervals[i];
if (cur[0] == pre[0] && cur[1] >= pre[1]) { // pre 屬於 cur
res++;
} else if (cur[1] <= pre[1]) { // cur 屬於 pre
res++;
pre = cur;
} else if (cur[0] < pre[1]) { // cur pre 相交
res++;
} else {
pre = cur;
}
}
return res;
}
}
- 複雜度分析
時間複雜度:排序的複雜度O(nlogn) 遍歷複雜度O(n)
空間複雜度:排序棧空間O(nlogn)