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是向最后一个重叠区域射箭

启发和联系