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 }