LeetCode,参考452. 用最少数量的箭引爆气球 。
题目
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points
,其中points[i] = [xstart, xend]
表示水平直径在 xstart
和 xend
之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x
处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart
,xend
, 且满足 xstart ≤ x ≤ xend
,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points
,返回引爆所有气球所必须射出的 最小 弓箭数 。
输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。
解题思路
- 排序:想要贪心的射到更多的气球,可以射到气球时限定区间,遇到相交区间时可以缩短区间到相交部分,直到区间不相交,开始射下一区间的气球,这样做的前提需要先对区间排序,以下注释代码选择对区间左端点排序。
排序
class Solution {
public int findMinArrowShots(int[][] points) {
//相当于找points里的相交区间,合并区间 合并过的不再合并,最终区间数即为弓箭数
//先排序 直接a[0]-b[0]可能会溢出所以手动赋值-1,1,0
Arrays.sort(points,(a,b)->a[0]<b[0]?-1:(a[0]>b[0]?1:0));
int min = points[0][0],max = points[0][1],ans = 1;
for(int[] point : points) {
if(point[0] > max){
ans++;
min = point[0];
max = point[1];
} else {
min = point[0];
max = Math.min(max,point[1]);
}
}
return ans;
}
}
复杂度分析
- 时间复杂度:
O(nlogn)
,n
为区间数,排序需要nlogn
时间为主要部分,枚举为n
。 - 空间复杂度:
O(1)
,只使用常数(2)个变量。
网友评论