贪心算法求解区间调度问题:
正确的思路其实很简单,可以分为以下三步:
-
从区间集合 intvs 中选择一个区间 x,这个 x 是在当前所有区间中结束最早的(end 最小)。
-
把所有与 x 区间相交的区间从区间集合 intvs 中删除。
-
重复步骤 1 和 2,直到 intvs 为空为止。之前选出的那些 x 就是最大不相交子集
435. 无重叠区间
bool compare(vector<int>& a, vector<int>& b) {
return a[1] < b[1];
}
class Solution {
public:
// bool compare(vector<int>& a, vector<int>& b) {
// return a[1] < b[1];
// }
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
const int n = intervals.size();
if(n <= 1) return 0;
sort(intervals.begin(), intervals.end(), compare);
int count = 1;
int end = intervals[0][1];
for(int i = 1; i < intervals.size(); i++) {
if(end <= intervals[i][0]) {
end = intervals[i][1];
count++;
}
}
return intervals.size()-count;
}
};
这道题和区间调度算法一模一样,等价于区间调度算法(求最大不重叠子区间个数),只不过在这里边界重叠也算作重叠。
bool compare(vector<int>& a, vector<int>& b) {
return a[1] < b[1];
}
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
int n = points.size();
if(n == 0) return 0;
sort(points.begin(), points.end(), compare);
int count = 1, curEnd = points[0][1];
for(int i = 1; i < points.size(); i++) {
if(curEnd < points[i][0]) {
count++;
curEnd = points[i][1];
}
}
return count;
}
};