自学内容网 自学内容网

[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)!