452. 用最少數量的箭引爆氣球

xxZkj發表於2020-11-23

452. 用最少數量的箭引爆氣球

在二維空間中有許多球形的氣球。對於每個氣球,提供的輸入是水平方向上,氣球直徑的開始和結束座標。由於它是水平的,所以縱座標並不重要,因此只要知道開始和結束的橫座標就足夠了。開始座標總是小於結束座標。

一支弓箭可以沿著 x 軸從不同點完全垂直地射出。在座標 x 處射出一支箭,若有一個氣球的直徑的開始和結束座標為 xstart,xend, 且滿足 xstart ≤ x ≤ xend,則該氣球會被引爆。可以射出的弓箭的數量沒有限制。 弓箭一旦被射出之後,可以無限地前進。我們想找到使得所有氣球全部被引爆,所需的弓箭的最小數量。

思路

  • 很容易想到排序,可以對氣球的起點從小到大排序,此時定義能射爆氣球範圍的右邊值為pre,射爆第一個氣球時,pre = points[0][1],然後可以遍歷氣球,判斷下一個氣球的起點是否在pre左邊,在的話則需要更新pre = min(pre, points[i][1]),否則,ans需要++,pre = points[i][1]。
class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        if(points.empty()) {
            return 0;
        }
        sort(points.begin(), points.end(), [](const vector<int>& a, const vector<int>& b) {
            return a[0] < b[0];
        });
        int ans = 1, pre = points[0][1];
        for(int i = 1; i < points.size(); i++) {
            if(points[i][0] > pre) {
                ans++;
                pre = points[i][1];
            }
            else {
                pre = min(pre, points[i][1]);
            }
        }
        return ans;
    }
};
  • 如果對氣球的終點進行排序,思路也大體一致,只是在遍歷氣球時,只需判斷pre和points[i][0]的大小更新pre和ans即可,因為points[i][1]的值肯定比pre大。
class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        if(points.empty()) {
            return 0;
        }
        sort(points.begin(), points.end(), [](const vector<int>& a, const vector<int>& b) {
            return a[1] < b[1];
        });
        int ans = 1, pre = points[0][1];
        for(int i = 1; i < points.size(); i++) {
            if(points[i][0] > pre) {
                ans++;
                pre = points[i][1];
            }
        }
        return ans;
    }
};

相關文章