用最少数量的箭引爆气球(贪心,区间)

有一些球形气球贴在一堵用\(XY\)平面表示的墙面上。墙面上的气球记录在整数数组\(points\),其中\(points[i] = [x_{start}, x_{end}]\)表示水平直径在\(x_{start}\)\(x_{end}\)之间的气球。你不知道气球的确切\(y\)坐标。

一支弓箭可以沿着\(x\)轴从不同点完全垂直地射出。在坐标\(x\)处射出一支箭,若有一个气球的直径的开始和结束坐标为\(x_{start}\)\(x_{end}\), 且满足\(x_{start} ≤ x ≤ x_{end}\),则该气球会被 引爆 。可以射出的弓箭的数量 没有限制。弓箭一旦被射出之后,可以无限地前进。
给你一个数组\(points\),返回引爆所有气球所必须射出的最小弓箭数 。

示例 1:
输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:

  • 在x = 6处射出箭,击破气球[2,8]和[1,6]。
  • 在x = 11处发射箭,击破气球[10,16]和[7,12]。

示例 2:
输入:points = [[1,2],[3,4],[5,6],[7,8]]
输出:4
解释:每个气球需要射出一支箭,总共需要4支箭。

示例 3:
输入:points = [[1,2],[2,3],[3,4],[4,5]]
输出:2
解释:气球可以用2支箭来爆破:

  • 在x = 2处发射箭,击破气球[1,2]和[2,3]。
  • 在x = 4处射出箭,击破气球[3,4]和[4,5]。

提示:
\(1 <= points.length <= 10^5\)
\(points[i].length == 2\)
\(-2^{31} <= x_{start} < x_{end} <= 2^{31} - 1\)

我们把气球看做区间,箭还是箭,箭是垂直向上射出。

首先,对于右端点最小的那个区间,如果想要用箭穿过它,那么一定从它的右端点穿过(从右端点穿过才只会穿过更多的区间)。
接下来,对于这只箭能未能穿过的区间,再从中找出右端点最小的区间。对于这只箭未能穿过的区间,如此往复的找下去。最终我们使用的箭数就是最少的。
image

------------------------------------------------图1--------------------------------

如何寻找第一个右端点最小的区间,以及在未被第一支箭穿过的剩余区间中,继续寻找第一个右端点最小的区间呢?

当我们把每个区间按照右端点升序排序后,显然第一个区间就是我们最开始要找的第一个区间,后序也可以进一步找到满足条件的最小右端点区间。具体的过程如下:

首先将区间按照右端点升序排序,此时位序为1的区间就是我们要找的第一个区间(图1),我们需要记录下第一个区间的右端点right(射出第一支箭),然后继续遍历,此时就会存在两种情况:

对于左端点小于等于right的区间,说明该区间能被前面的箭(right)穿过。
对于接下来左端点大于right的区间,说明前面这支箭无法穿过该区间(即:该区间就是未被箭穿过的区间集合的第一个区间),我们又找到了第一个未被箭穿过的区间,此时我们用一把新的箭穿过该区间的右端点(即更新right:right = points[i][1]),并将使用的箭数+1。如此往复。

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        int n=points.size();
        if(n==0){
            return 0;
        }
        sort(points.begin(),points.end(),[&](vector<int> a,vector<int> b){
            return a[1]<b[1];
        });
        int result = 1;
        // 第一支箭直接射出
        int arrow = points[0][1];
        for(int i=1;i<n;i++){
            if(points[i][0]<=arrow){
                continue;
            }
            arrow=points[i][1];
            result++;
        } 
        return result;
    }
};
posted @ 2023-12-29 14:35  lipu123  阅读(35)  评论(0)    收藏  举报