Non-overlapping Intervals 无重叠区间

给定一个区间的集合,找到须要移除区间的最小数量,使剩余区间互不重叠。算法

注意:数组

  1. 能够认为区间的终点老是大于它的起点。
  2. 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。

示例 1:code

输入: [ [1,2], [2,3], [3,4], [1,3] ]

输出: 1

解释: 移除 [1,3] 后,剩下的区间没有重叠。

示例 2:排序

输入: [ [1,2], [1,2], [1,2] ]

输出: 2

解释: 你须要移除两个 [1,2] 来使剩下的区间没有重叠。

示例 3:数学

输入: [ [1,2], [2,3] ]

输出: 0

解释: 你不须要移除任何区间,由于它们已是无重叠的了。

思路:这道题先说解法,首先按照结束时间排序,而后遍历数组,先把第一个元素加进答案中,而后遍历后面的元素,若是后面元素的起始时间和截止时间包含第一个元素,就跳过。不然就把元素加入答案。伪代码以下:it

Sort jobs by finish times so that f1 <= f2 <= ... <= fn.
select a task ——>A 
for j = 1 to n {
   if (job j compatible with A)
      A and {j} ——> A
}
return A

其实贪心算法若是简单的题好理解(好比01背包问题),可是对于这类直接给出结论的确实让人难以理解,为何那么多种其余组合,这种解法就能获得最优解呢?下面给出证实:io

首先,该算法选出的区间是互不重叠的。ast

 其次,设fi为该算法所接受的第i个区间的右端点坐标,gi为某最优解中的第i个区间的右端点坐标。class

命题1.1 当i>=1时,该算法所接受的第i个区间的右端点坐标fi<=某最优解中的第i个区间的右端点坐标gi。select

该命题能够运用数学概括法来证实。对于i=1,命题显然为真,由于算法第一个选择的区间拥有最小右端点坐标。令i>1,假定论断对i-1为真,即fi-1<=gi-1。则最优解的第i个可选区间所组成的集合包含于执行该算法时第i个可选区间所组成的集合;而当算法选择第i个区间时,选的是在可选区间中右端点坐标最小的一个(意思就是说对于最优解而言,第i个区间能够选择的区间是一个集合,不仅一个,而该算法选择的是右边结束时间最少的那个区间(集合中的区间的其中一个),),因此有fi<=gi。证毕。

设该算法选出了k个区间,而最优解选出了m个区间。

命题1.2  最优解选出的区间数量m=该算法选出的区间数量k。

假设m>k,根据命题1.1,有fk<=gk。因为m>k,必然存在某区间,在gk以后开始,故也在fk以后开始。而该算法必定不会在选了第k个区间后中止,还会选择更多的区间,产生矛盾。因此m<=k,又由于m是最优解选出区间个数,因此m>=k。,于是m=k.

综上所述,算法选出的区间是最优解。

参考代码:

/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
    static bool mycmp(const Interval &a, const Interval &b) {
	    return a.end < b.end;
    }
    int eraseOverlapIntervals(vector<Interval>& intervals) {
	if (intervals.size() == 0) return 0;
	int count=1;
	sort(intervals.begin(), intervals.end(), mycmp);
	Interval lastInterval=intervals[0];
	for (int i = 1; i < intervals.size(); i++) {
		if (intervals[i].start < lastInterval.end && lastInterval.end <= intervals[i].end) continue;
		else lastInterval = intervals[i], count++;
	}
	return intervals.size() - count;        
    }
};