boxmoe_header_banner_img

Hello! 欢迎来到不如画七的空间!

加载中

文章导读

13.用最少数量的箭引爆气球


avatar
ensiezadi 2025年8月28日 41

用最少数量的箭引爆气球

题目

在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以纵坐标并不重要,因此只要知道开始和结束的横坐标就足够了。开始坐标总是小于结束坐标。

一支弓箭可以沿着 x 轴从不同点完全垂直地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 x_start,x_end, 且满足 x_start ≤ x ≤ x_end,则该气球会被引爆。可以射出的弓箭的数量没有限制。 弓箭一旦被射出之后,可以无限地前进。我们想找到使得所有气球全部被引爆,所需的弓箭的最小数量。

给你一个数组 points ,其中 points [i] = [x_start,x_end] ,返回引爆所有气球所必须射出的最小弓箭数。

具体思路

  • 按照区间左端点排序
  • 当区间重合时,说明可以一只箭射爆两个
  • 问题就是:如何再顺利的连接起当前已经射爆的,和下一个继续进行比较
  • :更新比较的右端点

问题:该如何决定遍历顺序,要从第二个位置开始,向之前那个位置进行排序

具体代码

class Solution {
public:
    static bool cmp(vector<int>& a, vector<int>& b) { return a[0] < b[0]; }
    int findMinArrowShots(vector<vector<int>>& points) {
        int res = 1;
        sort(points.begin(), points.end(), cmp);
        for (int i = 1; i < points.size(); i++) {
            // 注意小于等于的情况
            // 当前区间和上一区间进行比较,那么下一轮中,当前区间就要成为上一区间
            // 就应该更新区间的右端点,保证两者同时射爆,就要选最短的那个
            if (points[i][0] <= points[i - 1][1])
                points[i][1] = min(points[i][1], points[i - 1][1]);
            else
                res++;
        }
        return res;
    }
};

class Solution {
    public int findMinArrowShots(int[][] points) {
        Arrays.sort(points, (x, y) -> {
            return x[0] == y[0] ? x[1] - y[1] : x[0] - y[0];
        });

        int res = 1;
        int curStart = points[0][0];
        int curEnd = points[0][1];
        for (int i = 1; i < points.length; i++) {
            curStart = Math.max(points[i][0], curStart);
            curEnd = Math.min(points[i][1], curEnd);
            if (curStart > curEnd) {
                res++;
                curStart = points[i][0];
                curEnd = points[i][1];
            }
        }
        return res;
    }
}


评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码
不如画七
2025 年 10 月
 123456
78910111213
14151617181920
21222324252627
282930