[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 xendbursts 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

Explanation:
One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).

给一堆气球,用区间[start,end]来表示气球大小,会有重叠区间。箭从某一个位置发射,只要区间包含这个点的就可以被射中。求用最少的箭数将所有的气球打爆。

解法:贪婪算法Greedy,先给区间排序,遍历区间,第一个区间时,先加1箭,记录区间的end,然后比较后面的区间的start,如果start <= end,说明两个区间有重合,箭从重合区间发射就可以同时打爆这两个气球。重新记录这两个区间里end小的值,在和后面的气球比较。如果start > end,说明没有重合区间,得在发射1箭,箭数加1。遍历结束就能得到所需的最少箭数。

Java:

public class Solution {
    public int findMinArrowShots(int[][] points) {
    if(points==null || points.length==0) return 0;

    Arrays.sort(points, ( x , y) -> x[0] == y[0] ? x[1] - y[1] : x[0] - y[0]);
    int count = 1;
    int arrowLimit = points[0][1];
    //贪心法,基于上一个箭,记录当前能够射穿的所有
    for(int i = 1;i < points.length;i++) {
        if(points[i][0] <= arrowLimit) {
            arrowLimit = Math.min(arrowLimit, points[i][1]);
        } else {
            count++;
            arrowLimit = points[i][1];
        }
    }
    return count;
    }
}

Python:

class Solution(object):
    def findMinArrowShots(self, points):
        """
        :type points: List[List[int]]
        :rtype: int
        """
        if not points:
            return 0

        points.sort()

        result = 0
        i = 0
        while i < len(points):
            j = i + 1
            right_bound = points[i][1]
            while j < len(points) and points[j][0] <= right_bound:
                right_bound = min(right_bound, points[j][1])
                j += 1
            result += 1
            i = j
        return result

C++:

class Solution {
public:
    int findMinArrowShots(vector<pair<int, int>>& points) {
        if (points.empty()) {
            return 0;
        }

        sort(points.begin(), points.end());

        int result = 0;
        for (int i = 0; i < points.size(); ++i) {
            int j = i + 1;
            int right_bound = points[i].second;
            while (j < points.size() && points[j].first <= right_bound) {
                right_bound = min(right_bound, points[j].second);
                ++j;
            }
            ++result;
            i = j - 1;
        }
        return result;
    }
};

  

  

All LeetCode Questions List 题目汇总

原文地址:https://www.cnblogs.com/lightwindy/p/8628228.html