1. 程式人生 > >LeetCode 題解:452. Minimum Number of Arrows to Burst Balloons

LeetCode 題解:452. Minimum Number of Arrows to Burst Balloons

There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it’s horizontal, y-coordinates don’t matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 104 balloons.

An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons.

Example:

Input:
[[10,16], [2,8], [1,6], [7,12]]

Output:
2

解題思路

這道題的解決思路其實就是找重疊區間最多的位置x的數量。此題採用貪心演算法求解。演算法共三步:

1、將儲存氣球位置的points陣列按照每個氣球的起始點的位置進行排序,便於後續操作。這裡使用系統內建的sort函式。

2、設定初始可以放置箭矢發射的位置空間為0號氣球的位置(排序後的points陣列的0號元素points[0]),放置箭矢發射的位置空間的右邊界用變數 end 記錄。

3、假如第x個氣球的左邊界小於當前記錄的 end 值,說明當前放置的箭矢可以射爆第x個氣球,箭矢的數量不需要增加。但要注意,第x個氣球的右邊界可能小於當前記錄的 end

值,此時需要將當前的重疊區域的右邊界更新為第x個氣球的右邊界。否則,假如第x個氣球的左邊界已經大於當前記錄的 end 值,那說明這個氣球不能被射爆,要使用新的箭矢。箭矢的數量要加1,同時將 end 值更新為第x個氣球的右邊界。重複上述步驟直到遍歷完所有氣球。

注:由於points陣列已經按照每個氣球的左邊界進行了排序,因此後面的演算法過程不再需要記錄氣球的左邊界的位置,因為從位置 end 射出的箭矢一定能射爆重疊區域的所有氣球。

C++程式碼

class Solution {
public:
    int findMinArrowShots(vector<pair<int, int>>& points) {
        if(points.empty()) return 0;
        
        sort(points.begin(), points.end(), [](const pair<int, int> a, const pair<int, int> b){ return a.first < b.first; });
        
        int arrows = 1;
        int end = points[0].second;
        
        for(int i = 1; i < points.size(); i++) {
            if(points[i].first <= end) {
                if(end >= points[i].second)
                    end = points[i].second;
            }
            else {
                arrows++;
                end = points[i].second;
            }
        }
        return arrows;
    }
};