【陪伴式刷题】Day 30|贪心算法|452.用最少数量的箭引爆气球🎈(Minimum Number of Arrows to Burst Balloons)

放在最前面的!!!当看到注意事项📋里有 -2^31<= x(start)< x(end)<= 2^31- 1 的时候,使用int类型的参数就要注意是否会越界叻!!!

题目描述

英文版描述

There are some spherical balloons taped onto a flat wall that represents the XY-plane. The balloons are represented as a 2D integer array points where points[i] = [x(start), x(end)] denotes a balloon whose horizontal diameter stretches between x(start) and x(end). You do not know the exact y-coordinates of the balloons.

Arrows can be shot up directly vertically (in the positive y-direction) from different points along the x-axis. A balloon with x(start) and x(end) is burst by an arrow shot at x if x(start) <= x <= x(end). There is no limit to the number of arrows that can be shot. A shot arrow keeps traveling up infinitely, bursting any balloons in its path.

Given the array points, return the minimum number of arrows that must be shot to burst all balloons.

Example 1:

  • Input: points = [[10,16],[2,8],[1,6],[7,12]] Output: 2 Explanation: The balloons can be burst by 2 arrows: Shoot an arrow at x = 6, bursting the balloons [2,8] and [1,6]. Shoot an arrow at x = 11, bursting the balloons [10,16] and [7,12].

Example 2:

Input: points = [[1,2],[3,4],[5,6],[7,8]] Output: 4 Explanation: One arrow needs to be shot for each balloon for a total of 4 arrows.

Example 3:

  • Input: points = [[1,2],[2,3],[3,4],[4,5]] Output: 2 Explanation: The balloons can be burst by 2 arrows: Shoot an arrow at x = 2, bursting the balloons [1,2] and [2,3]. Shoot an arrow at x = 4, bursting the balloons [3,4] and [4,5].

Constrains:

  • 1 <= points.length <= 10^5
  • points[i].length == 2
  • -2^31<= x(start)< x(end)<= 2^31- 1

英文版地址

leetcode.com/problems/mi...

中文版描述

有一些球形气球贴在一堵用 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 ,返回引爆所有气球所必须射出的 最小 弓箭数

示例 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 <= 10^5
  • points[i].length == 2
  • -2^31<= x(start)< x(end)<= 2^31- 1

中文版地址

leetcode.cn/problems/mi...

解题方法

俺这版

有点过于慢了哈= =

java 复制代码
class Solution {
    public int findMinArrowShots(int[][] points) {
        if (points == null) {
            return 0;
        }
        if (points.length == 1) {
            return 1;
        }
        Arrays.sort(points, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                if (o1[0] != o2[0]) {
                    return o1[0] > o2[0] ? 1 : -1;
                } else {
                    return o1[1] > o2[1] ? 1 : -1;
                }
            }
        });
        long[] step = new long[2];
        step[0] = points[0][0];
        step[1] = points[0][1];
        int result = 1;
        for (int i = 1; i < points.length; i++) {
            if (step[1] >= points[i][0]) {
                if (step[1] > points[i][1]) {
                    step[0] = points[i][0];
                    step[1] = points[i][1];
                }
            } else {
                result++;
                step[0] = points[i][0];
                step[1] = points[i][1];
            }
        }
        return result;
    }
}

复杂度分析

  • 时间复杂度:O(n),其中 n 是数组大小
  • 空间复杂度:O(1)

官方版

java 复制代码
class Solution {
    public int findMinArrowShots(int[][] points) {
        Arrays.sort(points, (a, b) -> Integer.compare(a[0], b[0]));
        int count = 1;
        for (int i = 1; i < points.length; i++) {
            if (points[i][0] > points[i - 1][1]) {
                count++;
            } else {
                points[i][1] = Math.min(points[i][1], points[i - 1][1]);
            }
        }
        return count;
    }
}

复杂度分析

  • 时间复杂度:O(NlogN),其中 n 是数组大小,主要是排序耗费的时间
  • 空间复杂度:O(logN),java所使用的内置函数用的是快速排序需要 logN 的空间

总结 >> 今天的最近很多嘿嘿( ̄∇ ̄)/

可以看到官方版在执行的时间复杂度、空间复杂度都表现的更好,并且在自定义比较器时,采用Integer.compare(a[0], b[0])),即Integer内置比较方法,不会溢出,案例中有一个int[][] points = {{-2147483646, -2147483645}, {2147483646, 2147483647}};(我就是卡在了这个案例,本地Debug才发现这个例子中-2147483646和2147483646做差会导致超出Integer的范围(Integer的取值范围是从-2147483648 至 2147483647(-2^31至2^31-1))导致排序出错),也可以用我那版中的方法:o1[0] > o2[0] ? 1 : -1;,反正就是避免元素出界。

后面的逻辑就很类似了,就是比较然后更新重叠的边界。

根据这个 版本,我考虑了下,其实也没有必要排两次序(第一版慢的原因应该就是排序这里),做了下优化

果然,时间快了很多= =,不过有一点我很迷惑,当我仅仅把比较器中的o1[0] > o2[0] ? 1 : -1换成Integer.compare(o1[0], o2[0]),空间复杂度就优秀了很多(Why?)

我专门看了Integer.compare()方法的源码,也是三目运算符啊🤔

于是我用同样的形式,发现居然空间复杂度也是这么优秀(Why?)

改得再直观一点

只是一个大于小于的差别,空间复杂度就不一样了?当我又执行一次后。。。

呃,再来。。。

同志们啊,Leetcode的这个是时间复杂度跟空间复杂度好像也不是那么靠谱哎(˶‾᷄ ⁻̫ ‾᷅˵),可能是数据集不同导致的差别?(>>>是的吧 = =)

好的,就是这个发现(之前我一直都挺信Leetcode上的这俩参数的)

搞定!撒花🎉~~~

相关推荐
dj24429457076 分钟前
JAVA中的Lamda表达式
java·开发语言
工业3D_大熊19 分钟前
3D可视化引擎HOOPS Luminate场景图详解:形状的创建、销毁与管理
java·c++·3d·docker·c#·制造·数据可视化
szc176723 分钟前
docker 相关命令
java·docker·jenkins
程序媛-徐师姐32 分钟前
Java 基于SpringBoot+vue框架的老年医疗保健网站
java·vue.js·spring boot·老年医疗保健·老年 医疗保健
yngsqq33 分钟前
c#使用高版本8.0步骤
java·前端·c#
尘浮生43 分钟前
Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
小白不太白9501 小时前
设计模式之 模板方法模式
java·设计模式·模板方法模式
Tech Synapse1 小时前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端
xoxo-Rachel1 小时前
(超级详细!!!)解决“com.mysql.jdbc.Driver is deprecated”警告:详解与优化
java·数据库·mysql