452. 用最少数量的箭引爆气球
1. 题目
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points
,其中points[i] = [xstart, xend]
表示水平直径在 xstart
和 xend
之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x
处射出一支箭,若有一个气球的直径的开始和结束坐标为 x``start
,x``end
, 且满足 xstart ≤ x ≤ x``end
,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points
,返回引爆所有气球所必须射出的 最小 弓箭数 。
示例 1:
1 | 输入:points = [[10,16],[2,8],[1,6],[7,12]] |
示例 2:
1 | 输入:points = [[1,2],[3,4],[5,6],[7,8]] |
示例 3:
1 | 输入:points = [[1,2],[2,3],[3,4],[4,5]] |
提示:
1 <= points.length <= 10^5
points[i].length == 2
-2^31 <= xstart < xend <= 2^31 - 1
2. 思路
- 已知题目要求最少数量的箭来引爆气球,因此根据下图可以分析得到,要尽可能地一次打穿多个气球,最佳条件应该是满足尽可能多的区间的情况下,应当射击区间中最左的右边界(因为这样既能够射中最左边的气球,也能够尽可能多地延展出去射击更多的气球)
- 在开始前需要对气球区间数组
points
进行排序,排序需要使用气球的右边界进行排序,使用右边界排序能够保证所有的右边界是递增趋势 - 初始化结果变量
result
与相同区间最左的右边界变量sameIntervalLeftBorder
为第一个气球的右边界 - 遍历排序后的气球区间数组
points
,当出现当前气球区间的左区间point[0]
比sameIntervalLeftBorder
变量大时,意味着已经无法再射击更多的气球了,气球区间已经超出范围了,不会再出现重叠的部分以供射击 - 因此对
result
变量进行+1,意味着需要多一次射击,同时更新sameIntervalLeftBorder
为point[1]
- 遍历直至数组结束,返回结果变量
result
- 简单地理解,该算法就是在保证最左的右边界的同时,看看能否尽可能多的覆盖到气球区间,如果没法覆盖了,则对结果变量进行自增,同时更新最左的右边界变量,以此反复
3. 代码
1 | class Solution { |
4. 复杂度
- 时间复杂度:O(nlogn)
- 空间复杂度:O(n)