文章目录
435. 无重叠区间
题目描述
给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
示例 1:
输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
示例 2:
输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
示例 3:
输入: intervals = [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
提示:
- 1 <= intervals.length <= 10^5^
- intervals[i].length == 2
- -5 * 104 <= starti < endi <= 5 * 10^4^
贪心算法
这段代码是用来解决"435. 无重叠区间"这个问题的C++解。下面对代码进行详细注释,解释其工作原理和关键步骤。
cpp
class Solution {
public:
// 自定义比较函数,用于sort算法对区间进行排序
// 根据区间的起始位置进行升序排序
static bool cmp(vector<int> a, vector<int> b) {
return a[0] < b[0];
}
// 函数用于找出最少需要移除的区间数量,以使得剩余的区间互不重叠
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
// 首先,使用自定义的比较函数对区间进行排序
sort(intervals.begin(), intervals.end(), cmp);
// 初始化计数器,用于记录需要移除的区间数量
int count = 0;
// 遍历排序后的区间列表,从第二个区间开始比较
for (int i = 1; i < intervals.size(); i++) {
// 如果当前区间的起始位置大于或等于前一个区间的结束位置,
// 表示这两个区间不重叠,不需要进行任何操作,直接继续遍历
if (intervals[i][0] >= intervals[i - 1][1])
continue;
else {
// 如果当前区间与前一个区间重叠,则需要移除一个区间
// 移除区间的策略是保留结束位置较小的区间,这样可以给后续区间留下更多空间,减少重叠的可能性
// 因此,这里更新当前区间的结束位置为两个区间结束位置的最小值
count++;
intervals[i][1] = min(intervals[i][1], intervals[i - 1][1]);
}
}
// 返回需要移除的区间数量
return count;
}
};
解题思路:
-
排序:首先,按照区间的起始位置对所有区间进行排序,使得比较和处理区间时有一个确定的顺序。
-
遍历处理:从第二个区间开始向后遍历,比较每个区间与其前一个区间的位置关系。
-
无重叠判断:如果当前区间的起始位置大于或等于前一个区间的结束位置,则这两个区间不重叠,无需移除。
-
移除重叠区间策略:如果当前区间与前一个区间重叠,则通过比较结束位置来确定保留哪个区间。策略是保留结束位置较小的区间,因为这样做可以为后面的区间留出尽可能多的空间,从而减少整体的重叠数量。在这个过程中,需要移除的区间数量加一。
-
返回结果 :遍历完成后,
count
变量中存储的就是需要移除的区间数量,最后返回这个结果。