Leetcode Link: 452. 用最少数量的箭引爆气球 - 力扣(LeetCode)
题目
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points ,其中points[i] = [x_start, x_end] 表示水平直径在 x_start 和 x_end之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 x_start,x_end, 且满足 x_start ≤ x ≤ x_end,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points ,返回引爆所有气球所必须射出的 最小 弓箭数 。

解法一
思路: 贪心,每一个箭都射爆最多的气球。
想让每一个箭都射爆最多的气球,就需要知道相邻的气球有没有重叠范围,因此需要对气球进行排列。
但是依靠什么进行排列呢?这里依靠每个气球的起始点 x_start
排列好逐个计算重叠区域,基本可以肯定的是,随着看的相邻的气球越来越多,重叠区域一定会越来越小直到没有。当重叠区域为 0 的时候,我们就射出一支箭将上一个重叠区域的所有气球射爆。
注意最后一个重叠区域要射一个箭
题解:
class Solution:
def findMinArrowShots(self, points: List[List[int]]) -> int:
#### 排序过程
points.sort(key = lambda x: x[1]) # 按照右端点升序排列
#### 射箭过程
res = 0
cover = [-float('inf'), float('inf')] # 初始化,全范围
for p in range(len(points)):
# 重叠区域和当前气球范围有重叠,则更新重叠区域
if cover[1]>=points[p][0]: # 重叠区域终点和当前起点有重叠
cover = [max(points[p][0], cover[0]), min(points[p][1], cover[1])]
else: # 无重叠,则重置重叠区域,并向上一个重叠区域射箭
res += 1
cover = points[p]
return res+1 # 最后加1是向最后一个重叠区域射箭