Description Submission Solutions Add to Listjava
Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.算法
Note:數據結構
Example 1:app
Input: [ [1,2], [2,3], [3,4], [1,3] ] Output: 1 Explanation: [1,3] can be removed and the rest of intervals are non-overlapping.
Example 2:this
Input: [ [1,2], [1,2], [1,2] ] Output: 2 Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping.
Example 3:spa
Input: [ [1,2], [2,3] ] Output: 0 Explanation: You don't need to remove any of the intervals since they're already non-overlapping.
Subscribe to see which companies asked this question..net
【題目分析】rest
這個題目與《算法導論》中活動安排的題目很是相似。code
活動選擇問題
有n個須要在同一天使用同一個教室的活動a1,a2,…,an,教室同一時刻只能由一個活動使用。每一個活動ai都有一個開始時間si和結束時間fi 。一旦被選擇後,活動ai就佔據半開時間區間[si,fi)。若是[si,fi]和[sj,fj]互不重疊,ai和aj兩個活動就能夠被安排在這一天。該問題就是要安排這些活動使得儘可能多的活動能不衝突的舉行。例以下圖所示的活動集合S,其中各項活動按照結束時間單調遞增排序。blog
考慮使用貪心算法的解法。爲了方便,咱們用不一樣顏色的線條表明每一個活動,線條的長度就是活動所佔據的時間段,藍色的線條表示咱們已經選擇的活動;紅色的線條表示咱們沒有選擇的活動。
若是咱們每次都選擇開始時間最先的活動,不能獲得最優解:
若是咱們每次都選擇持續時間最短的活動,不能獲得最優解:
能夠用數學概括法證實,咱們的貪心策略應該是每次選取結束時間最先的活動。直觀上也很好理解,按這種方法選擇相容活動爲未安排活動留下儘量多的時間。這也是把各項活動按照結束時間單調遞增排序的緣由。
【思路】
參照上面活動安排的例子,咱們很容易獲得這個題目的解法。這是一個貪心問題,咱們每次都找到那個結束點最小的區間,而後依次向後找那些與前面區間不衝突且結束點早的區間。這個過程當中咱們把局部的最優解合併成了全局的最優解。
【java代碼】
1 /** 2 * Definition for an interval. 3 * public class Interval { 4 * int start; 5 * int end; 6 * Interval() { start = 0; end = 0; } 7 * Interval(int s, int e) { start = s; end = e; } 8 * } 9 */ 10 public class Solution { 11 public int eraseOverlapIntervals(Interval[] intervals) { 12 if(intervals.length == 0) return 0; 13 14 Comparator<Interval> comp = new Comparator<Interval>() { 15 public int compare(Interval interval1, Interval interval2) { 16 if(interval1.end > interval2.end) return 1; 17 else if(interval1.end < interval2.end) return -1; 18 else return 0; 19 } 20 }; 21 22 Arrays.sort(intervals, comp); 23 int lastend = intervals[0].end; 24 int remove = 0; 25 for(int i = 1; i < intervals.length; i++) { 26 if(intervals[i].end == lastend) remove++; 27 else if(intervals[i].start < lastend) remove++; 28 else lastend = intervals[i].end; 29 } 30 31 return remove; 32 } 33 }