452. Minimum Number of Arrows to Burst Balloons
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
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).
方法1: greedy
官方题解:https://leetcode.com/problems/minimum-number-of-arrows-to-burst-balloons/solution/
根据气球的end来排序,能射掉多少射多少。
Let’s sort the balloons by the end coordinate, and then check them one by one. The first balloon is a green one number 0, it ends at coordinate 6, and there is no balloons ending before it because of sorting.
The other balloons have two possibilities :
-
To have a start coordinate smaller than 6, like a red balloon. These ones could be burst together with the balloon 0 by one arrow.
-
To have a start coordinate larger than 6, like a yellow balloon. These ones couldn’t be burst together with the balloon 0 by one arrow, and hence one needs to increase the number of arrows here.
That means that one could always track the end of the current balloon, and ignore all the balloons which end before it. Once the current balloon is ended (= the next balloon starts after the current balloon), one has to increase the number of arrows by one and start to track the end of the next balloon.
[4,11],
[1,10]
[[9,12]
[6,9]
[6,7]]
[3,9],
[8,12]
易错点:
- 注意这里的按照end sort至关重要:如果是默认的排序法,按照start排序,必须多加一步往回调整射箭点的步骤。
- 气球的range可能是[INT_MIN, INT_MAX],还是用第一个气球来initialize比较保险。
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
if (points.empty()) return 0;
sort(points.begin(), points.end(), [](vector<int> & a, vector<int> & b) {
if (a[1] == b[1]) return a[0] < b[0];
return a[1] < b[1];
});
int end = points[0][1], res = 1;
for (int i = 1; i < points.size(); i++) {
if (points[i][0] > end) {
res++;
end = points[i][1];
}
}
return res;
}
};
这个方法explicitly的解决了这个问题,首先我们按照默认规则给气球排序,然后从第一个点初始化,propose的射箭点是10,然后寻找所有start小于这个位置的气球,这些气球都可以burst掉,但是有的end会< 10,这时我们射箭点就要调整,end = min(end, points[i][1])。这个调整仍然能够保证之前的气球能打破(推一下)。如果出现了范围外的气球,必须重新拔一根箭,res++,end被更新。
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
if (points.empty()) return 0;
sort(points.begin(), points.end());
int res = 1, end = points[0][1];
for (int i = 1; i < points.size(); i++) {
if (points[i][0] <= end) {
end = min(end, points[i][1]);
}
else {
end = points[i][1];
res++;
}
}
return res;
}
};