力扣经典150题第五十题:用最少数量的箭引爆气球

简介: 力扣经典150题第五十题:用最少数量的箭引爆气球

题目描述和要求

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

一支弓箭可以沿着 x 轴从不同点完全垂直地射出。在坐标 x 处射出一支箭,若有一个气球的直径的开始和结束坐标为 xstart,xend,且满足 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. 将气球按照起始坐标进行排序。
  2. 初始化箭的数量为1,初始化当前箭的射击位置为第一个气球的结束坐标。
  3. 遍历排序后的气球,如果当前气球的起始坐标大于当前箭的射击位置,则需要一支新的箭,并更新当前箭的射击位置为当前气球的结束坐标。
  4. 返回箭的数量。

算法实现

import java.util.Arrays;
public class MinArrowsBurstBalloons {
    public int findMinArrowShots(int[][] points) {
        if (points == null || points.length == 0) {
            return 0;
        }
        Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
        int arrows = 1;
        int shootPos = points[0][1];
        for (int i = 1; i < points.length; i++) {
            if (points[i][0] > shootPos) {
                arrows++;
                shootPos = points[i][1];
            } else {
                shootPos = Math.min(shootPos, points[i][1]);
            }
        }
        return arrows;
    }
}

复杂度分析

  • 时间复杂度:O(nlogn),其中 n 为气球的数量。排序的时间复杂度为 O(nlogn),遍历一次气球的时间复杂度为 O(n)。
  • 空间复杂度:O(1),除了存储输入数组外,只需要常数级别的额外空间。

测试和验证

编写测试用例对算法进行验证,确保其正确性和健壮性。

public class Main {
    public static void main(String[] args) {
        MinArrowsBurstBalloons minArrowsBurstBalloons = new MinArrowsBurstBalloons();
        int[][] points1 = {{10,16},{2,8},{1,6},{7,12}};
        System.out.println(minArrowsBurstBalloons.findMinArrowShots(points1)); // 2
        int[][] points2 = {{1,2},{3,4},{5,6},{7,8}};
        System.out.println(minArrowsBurstBalloons.findMinArrowShots(points2)); // 4
        int[][] points3 = {{1,2},{2,3},{3,4},{4,5}};
        System.out.println(minArrowsBurstBalloons.findMinArrowShots(points3)); // 2
    }
}

总结和拓展

本题通过对气球按照起始坐标进行排序,并遍历气球的方式,实现了求解引爆所有气球所必须射出的最小弓箭数。这个算法思路清晰简单,在处理类似问题时是一个不错的选择。

此外,我们也可以考虑其他实现方式,例如使用贪心算法或动态规划等方法来解决类似问题。

参考资料

  • 《力扣经典150题》
  • LeetCode 官方网站
相关文章
|
7月前
|
Java
leetcode-452:用最少数量的箭引爆气球
leetcode-452:用最少数量的箭引爆气球
74 0
|
7月前
日拱一卒,月进一步(6)(杨辉三角2)
119. 杨辉三角 II - 力扣(LeetCode)
47 0
|
7月前
代码随想录Day29 贪心04 LeetCode T860 柠檬水找零 T406 根据身高重建队列 T452 用最少得箭引爆气球
代码随想录Day29 贪心04 LeetCode T860 柠檬水找零 T406 根据身高重建队列 T452 用最少得箭引爆气球
45 0
|
算法 Java
代码随想录算法训练营第三十四天 | LeetCode 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球
代码随想录算法训练营第三十四天 | LeetCode 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球
70 0
|
算法 Java 测试技术
LeetCode 周赛上分之旅 #46 经典二分答案与质因数分解
学习数据结构与算法的关键在于掌握问题背后的算法思维框架,你的思考越抽象,它能覆盖的问题域就越广,理解难度也更复杂。在这个专栏里,小彭与你分享每场 LeetCode 周赛的解题报告,一起体会上分之旅。
70 0
LeetCode 周赛上分之旅 #46 经典二分答案与质因数分解
leetcode 1921. 消灭怪物的最大数量(每日一题)
leetcode 1921. 消灭怪物的最大数量(每日一题)
87 0
leetcode 452用最少数量的箭引爆气球
leetcode 452用最少数量的箭引爆气球
93 0
leetcode 452用最少数量的箭引爆气球
(数论)蓝桥杯AcWing 1205. 买不到的数目
(数论)蓝桥杯AcWing 1205. 买不到的数目
56 0
代码随想录刷题|LeetCode 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球
代码随想录刷题|LeetCode 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球
代码随想录刷题|LeetCode 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球
|
机器学习/深度学习 算法 Windows
LeetCode 452. 用最少数量的箭引爆气球(贪心算法)
LeetCode 452. 用最少数量的箭引爆气球(贪心算法)
123 0