友情支持

如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜

支付宝

微信

有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。

wx jikerizhi

公众号的微信号是: jikerizhi因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。

452. 用最少数量的箭引爆气球

有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中 points[i] = [xstart, xend] 表示水平直径在 xstartxend 之间的气球。你不知道气球的确切 y 坐标。

一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstartxend,且满足 xstart ≤ x ≤ xend,则该气球会被 引爆 可以射出的弓箭的数量 没有限制 。弓箭一旦被射出之后,可以无限地前进。

给你一个数组 points返回引爆所有气球所必须射出的 最小 弓箭数

示例 1:

输入:points = [[10,16],[2,8],[1,6],[7,12]]
输出:2
解释:气球可以用2支箭来爆破:
-在x = 6处射出箭,击破气球[2,8]和[1,6]。
-在x = 11处发射箭,击破气球[10,16]和[7,12]。

示例 2:

输入:points = [[1,2],[3,4],[5,6],[7,8]]
输出:4
解释:每个气球需要射出一支箭,总共需要4支箭。

示例 3:

输入:points = [[1,2],[2,3],[3,4],[4,5]]
输出:2
解释:气球可以用2支箭来爆破:
- 在x = 2处发射箭,击破气球[1,2]和[2,3]。
- 在x = 4处射出箭,击破气球[3,4]和[4,5]。

提示:

  • 1 <= points.length <= 105

  • points[i].length == 2

  • -2^31^ <= x~start~ < x~end~ <= 2^31^ - 1

思路分析

0452 10

对坐标区间排序,然后进行区间合并,最后统计只剩几个区间即可。看题解,也不需要保存区间,只需要记录最后一个区间的右端就可以统计出区间数量。

看题解,说这是一道贪心算法的题。

  • 如果按照我上面合并区间的做法,那么就是一道 Merge Intervals 区间合并 的题目。

  • 如果按照贪心的思路来解题,首先排序时,需要根据右端位置排序。每次记录最右端的位置,拿当前区间的左端,跟目前最右端的位置进行比较,只有在没有交集时,才增大射箭数量。

看“代码随想录”的解释,D瓜哥的区间解法是贪心思路。
0452 11
  • 一刷

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * @author D瓜哥 · https://www.diguage.com
 * @since 2025-06-19 21:20:51
 */
public int findMinArrowShots(int[][] points) {
  Arrays.sort(points, Comparator.comparingInt(a -> a[0]));
  List<int[]> inter = new ArrayList<>();
  inter.add(points[0]);
  for (int i = 1; i < points.length; i++) {
    int[] point = points[i];
    int[] last = inter.getLast();
    if (last[1] < point[0]) {
      // 新区间在已处理区间的后面,则直接新增
      inter.add(point);
    } else {
      // 有重叠,则进行区间合并
      last[0] = Math.max(last[0], point[0]);
      last[1] = Math.min(last[1], point[1]);
    }
  }
  return inter.size();
}