LeetCode从低效到高效,点击
一、题目描述:
题目要求
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意 可以认为区间的终点总是大于它的起点。 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
来源:力扣(LeetCode)链接
示例
输入: [ [1,2], [2,3], [3,4], [1,3] ]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
二、思路分析:
这道题难就难在了需要检测左右两个边界,最开始我想到了当成DP去做,后来想到能不能固定一个边界,然后值判断另一个边界,发现也不太行,因为a的右边界可能碰到b的左边界. 但是如果对左边界进行排序,那么相邻的去区间只存在b的左边界与a的有边界相交/不相交,两种情况,当出现相交碰撞时这个两个区间是不能共同存在的,注意到无论保留哪个都不会影响之前的区间,那么这个时候只要保留右边界小的即可.
三、AC 代码:
// 16ms 9mb
int eraseOverlapIntervals(vector<vector<int>> &intervals)
{
if (intervals.size() == 0)
return 0;
sort(intervals.begin(), intervals.end(), [](vector<int> &x, vector<int> &y) {
return x[0] < y[0];
});
int flag = intervals[0][1];
int count = 0;
// 将第一个放进去,从第二个开始试
for (int i = 1; i < intervals.size(); i++)
{
// 发生碰撞,保留结尾小的那个,count不变,修正flag
if (intervals[i][0] < flag)
{
flag = min(flag, intervals[i][1]);
count++;
}
else
{
flag = intervals[i][1];
}
}
return count;
}
四、总结:
当判断条件非常多时,使用排序减少后续需要判断的数量是非常有效的策略.
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情