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

DawnTraveler發表於2024-06-19

1.題目介紹

題目地址(452. 用最少數量的箭引爆氣球 - 力扣(LeetCode))

https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/

題目描述

有一些球形氣球貼在一堵用 XY 平面表示的牆面上。牆面上的氣球記錄在整數陣列 points ,其中points[i] = [xstart, xend] 表示水平直徑在 xstartxend之間的氣球。你不知道氣球的確切 y 座標。

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

給你一個陣列 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 <= 105
  • points[i].length == 2
  • -231 <= xstart < xend <= 231 - 1

2.題解

2.1 貪心演算法

思路

看了這個圖,我就瞬間明白這題的考點了。

這裡我們還是考慮幾種貪心策略:
1.最小右邊界x_r
2.最大左邊界x_l
3.區間最短的邊界

我們如果想要一支箭貫穿最多的氣球,首先考慮木桶效應,因為我們知道區間長度較長的氣球,可以相容移動更長的射箭範圍,而真正限制我們的是那些較短的區間的氣球
我們還是從左到右遍歷,我們將射箭點從左往右移動的時候,貫穿的氣球數越來越多,直到一個極限點,到大最小右邊界的氣球右邊界,再往右這個氣球便無法貫穿,
我們不可能繼續向右移動,這樣我們就要單獨射出一支箭只為了解決這一個氣球;我們最好的選擇是在此射箭,選擇當前步驟的最優解,並準備下一次射箭(去除已經射爆的氣球)

程式碼

  • 語言支援:C++

C++ Code:

class Solution {
public:
    static bool compare(vector<int> p1, vector<int> p2){
        return p1[1] < p2[1];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        sort(points.begin(), points.end(), compare);
        int i = 0, cnt = 0;
        while(i < points.size()){
            cnt++;
            int rLen = points[i][1];
            while(++i < points.size() && points[i][0] <= rLen){}
        }
        return cnt;
    }
};

複雜度分析

令 n 為陣列長度。

  • 時間複雜度:\(O(n)\)
  • 空間複雜度:\(O(n)\)

相關文章