算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,后续每天带大家做一道算法题,题目就从LeetCode上面选 !
今天和大家聊的问题叫做 用最少数量的箭引爆气球,我们先来看题面:
https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons/
There are some spherical balloons taped onto a flat wall that represents the XY-plane. The balloons are represented as a 2D integer array points where points[i] = [xstart, xend] denotes a balloon whose horizontal diameter stretches between xstart and xend. You do not know the exact y-coordinates of the balloons.
Arrows can be shot up directly vertically (in the positive y-direction) from different points along the x-axis. A balloon with xstart and xend is burst by an arrow shot at x if xstart <= x <= xend. There is no limit to the number of arrows that can be shot. A shot arrow keeps traveling up infinitely, bursting any balloons in its path.
Given the array points, return the minimum number of arrows that must be shot to burst all balloons.
在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以纵坐标并不重要,因此只要知道开始和结束的横坐标就足够了。开始坐标总是小于结束坐标。
一支弓箭可以沿着 x 轴从不同点完全垂直地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend, 且满足 xstart ≤ x ≤ xend,则该气球会被引爆。可以射出的弓箭的数量没有限制。弓箭一旦被射出之后,可以无限地前进。我们想找到使得所有气球全部被引爆,所需的弓箭的最小数量。
给你一个数组 points ,其中 points [i] = [xstart,xend] ,返回引爆所有气球所必须射出的最小弓箭数。
示例 1:
输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:对于该样例,x = 6 可以射爆 [2,8],[1,6] 两个气球,以及 x = 11 射爆另外两个气球
示例 2:
输入:points = [[1,2],[3,4],[5,6],[7,8]]
输出:4
示例 3:
输入:points = [[1,2],[2,3],[3,4],[4,5]]
输出:2
示例 4:
输入:points = [[1,2]]
输出:1
示例 5:
输入:points = [[2,3],[2,3]]
输出:1
https://blog.csdn.net/mengyujia1234/article/details/89708885
先对给定数组排序,然后维护一个区间,定义区间的左边界为left,右边界为right。left的初始值为points[0][0],right的初始值为points[0][1],即初始的区间为第一个气球的范围。然后我们从第二个气球开始遍历,如果该气球与维护的区间有公共部分,那么更新区间为此公共部分,将left和right分别更新为该公共部分的左边界和右边界,然后 i++ 准备遍历下一个气球。否则如果该气球与维护的区间没有公共部分,那么将ans加1,然后将区间更新为该气球的范围,将left和right分别更新为该气球的左边界和右边界,然后 i++ 准备遍历下一个气球。接下来判断如果刚才遍历的这个气球已经是最后一个气球了,这意味着马上就要退出循环了,所以要将ans加1。退出循环后,返回ans。
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
if(points.size() <= 1)
return points.size();
sort(points.begin(), points.end());
int ans = 0;
int left = points[0][0];
int right = points[0][1];
int i = 1;
while(i < points.size()){
if(points[i][0] <= right && points[i][1] >= left){
left = max(left, points[i][0]);
right = min(right, points[i][1]);
}
else{
ans++;
left = points[i][0];
right = points[i][1];
}
i++;
if(i == points.size())
ans++;
}
return ans;
}
};
上期推文: