[Algorithm][贪心][合并区间][无重叠区间][用最少数量的箭引爆气球]详细讲解
1.合并区间
1.题目链接
2.算法原理详解
- 区间问题思路:
- 排序
- 左端点(本题)
- 右端点
- 根据排序后的结果,总结规律
- 排序
- 解法:排序(左端点) + 贪心
- 性质:能够合并的区间,都是连续的
- 如何合并?
- 求并集
- 求并集
3.代码实现
vector<vector<int>> merge(vector<vector<int>>& intervals)
{
// 排序
sort(intervals.begin(), intervals.end());
// 合并区间
vector<vector<int>> ret;
int left = intervals[0][0], right = intervals[0][1];
for(int i = 0; i < intervals.size(); i++)
{
int a = intervals[i][0], b = intervals[i][1];
if(a <= right) // 有重叠
{
right = max(right, b);
}
else // 无重叠
{
ret.push_back({left, right});
left = a;
right = b;
}
}
// 最后一个区间
ret.push_back({left, right});
return ret;
}
2.无重叠区间
1.题目链接
2.算法原理详解
- 解法:排序(左端点) + 贪心
- 问题转化:移除最少区间 <–> 保留更多区间
- 优先干掉右端点长的区间 --> 长的区间更后续区间重叠的概率更大
- 优先干掉右端点长的区间 --> 长的区间更后续区间重叠的概率更大
3.代码实现
int eraseOverlapIntervals(vector<vector<int>>& intervals)
{
// 排序
sort(intervals.begin(), intervals.end());
// 移除区间
int ret = 0;
int left = intervals[0][0], right = intervals[0][1];
for(int i = 1; i < intervals.size(); i++)
{
int a = intervals[i][0], b = intervals[i][1];
if(a < right) // 有重叠
{
ret++; // DELETE
right = min(right, b); // 贪心, 删除右端点较大的区间
}
else // 无重叠
{
right = b;
}
}
return ret;
}
3.用最少数量的箭引爆气球
1.题目链接
2.算法原理详解
- 问题抽象:区间问题
- 问题转化:最少的弓箭数量 --> 一只箭应该引爆更多的气球 --> 将互相重叠的所有区间都拿出来引爆
- 解法:排序(左端点) + 贪心
- 性质:按照左端点排序之后,互相重叠的区间是连续的(约束更强)
- 如何合并?
- 求交集
- 求交集
3.代码实现
int findMinArrowShots(vector<vector<int>>& points)
{
// 排序
sort(points.begin(), points.end());
// 求互相重叠区间的数量
int right = points[0][1];
int ret = 1;
for(int i = 1; i < points.size(); i++)
{
int a = points[i][0], b = points[i][1];
if(a <= right) // 有重叠
{
right = min(right, b);
}
else // 无重叠
{
ret++;
right = b;
}
}
return ret;
}
原文地址:https://blog.csdn.net/qq_37281656/article/details/142747797
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!