用最少数量的箭引爆气球[中等]

news2024/9/21 19:05:50

优质博文:IT-BLOG-CN

一、题目

有一些球形气球贴在一堵用XY平面表示的墙面上。墙面上的气球记录在整数数组points,其中points[i] = [xstart, xend]表示水平直径在xstartxend之间的气球。你不知道气球的确切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 <= points.length <= 105
points[i].length == 2
-231 <= xstart < xend <= 231 - 1

二、代码

排序 + 贪心: 我们首先随机地射出一支箭,再看一看是否能够调整这支箭地射出位置,使得我们可以引爆更多数目的气球。

如图1-1所示,我们随机射出一支箭,引爆了除红色气球以外的所有气球。我们称所有引爆的气球为「原本引爆的气球」,其余的气球为「原本完好的气球」。可以发现,如果我们将这支箭的射出位置稍微往右移动一点,那么我们就有机会引爆红色气球,如图1-2所示。那么我们最远可以将这支箭往右移动多远呢?我们唯一的要求就是:原本引爆的气球只要仍然被引爆就行了。这样一来,我们找出原本引爆的气球中右边界位置最靠左的那一个,将这支箭的射出位置移动到这个右边界位置,这也是最远可以往右移动到的位置:如图1-3所示,只要我们再往右移动一点点,这个气球就无法被引爆了。

为什么「原本引爆的气球仍然被引爆」是唯一的要求?别急,往下看就能看到其精妙所在。

因此,我们可以断定:一定存在一种最优(射出的箭数最小)的方法,使得每一支箭的射出位置都恰好对应着某一个气球的右边界。

这是为什么?我们考虑任意一种最优的方法,对于其中的任意一支箭,我们都通过上面描述的方法,将这支箭的位置移动到它对应的「原本引爆的气球中最靠左的右边界位置」,那么这些原本引爆的气球仍然被引爆。这样一来,所有的气球仍然都会被引爆,并且每一支箭的射出位置都恰好位于某一个气球的右边界了。

有了这样一个有用的断定,我们就可以快速得到一种最优的方法了。考虑所有气球中右边界位置最靠左的那一个,那么一定有一支箭的射出位置就是它的右边界(否则就没有箭可以将其引爆了)。当我们确定了一支箭之后,我们就可以将这支箭引爆的所有气球移除,并从剩下未被引爆的气球中,再选择右边界位置最靠左的那一个,确定下一支箭,直到所有的气球都被引爆。

我们可以写出如下的伪代码:

let points := [[x(0), y(0)], [x(1), y(1)], ... [x(n-1), y(n-1)]],表示 n 个气球
let burst := [false] * n,表示每个气球是否被引爆
let ans := 1,表示射出的箭数

将 points 按照 y 值(右边界)进行升序排序

while burst 中还有 falsedo
    let i := 最小的满足 burst[i] = false 的索引 i
    for j := i to n-1 do
        if x(j) <= y(i) then
            burst[j] := true
        end if
    end for
end while

return ans

这样的做法在最坏情况下时间复杂度是O(n^2),即这n个气球对应的区间互不重叠,while循环需要执行n次。那么我们如何继续进行优化呢?

事实上,在内层的j循环中,当我们遇到第一个不满足x(j)≤y(i)j值,就可以直接跳出循环,并且这个y(j)就是下一支箭的射出位置。为什么这样做是对的呢?我们考虑某一支箭的索引it以及它的下一支箭的索引jt​,对于索引在jt之后的任意一个可以被it引爆的气球,记索引为j0​,有:x(j0)≤y(it)由于y(it)≤y(jt)显然成立,那么x(j0)≤y(jt)也成立,也就是说:当前这支箭在索引jt​(第一个无法引爆的气球)之后所有可以引爆的气球,下一支箭也都可以引爆。因此我们就证明了其正确性,也就可以写出如下的伪代码:

let points := [[x(0), y(0)], [x(1), y(1)], ... [x(n-1), y(n-1)]],表示 n 个气球
let pos := y(0),表示当前箭的射出位置
let ans := 1,表示射出的箭数

将 points 按照 y 值(右边界)进行升序排序

for i := 1 to n-1 do
    if x(i) > pos then
        ans := ans + 1
        pos := y(i)
    end if
end for

return ans

这样就可以将计算答案的时间从O(n^2)降低至O(n)

class Solution {
    public int findMinArrowShots(int[][] points) {
        if (points.length == 0) {
            return 0;
        }
        Arrays.sort(points, new Comparator<int[]>() {
            public int compare(int[] point1, int[] point2) {
                if (point1[1] > point2[1]) {
                    return 1;
                } else if (point1[1] < point2[1]) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        int pos = points[0][1];
        int ans = 1;
        for (int[] balloon: points) {
            if (balloon[0] > pos) {
                pos = balloon[1];
                ++ans;
            }
        }
        return ans;
    }
}

时间复杂度: O(nlog⁡n),其中n是数组points的长度。排序的时间复杂度为O(nlog⁡n),对所有气球进行遍历并计算答案的时间复杂度为O(n),其在渐进意义下小于前者,因此可以忽略。
空间复杂度: O(log⁡n),即为排序需要使用的栈空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1273299.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Microsoft 365 for Mac:提升您的办公效率的终极选择

在现代工作环境中&#xff0c;高效的办公软件是提高工作效率和团队合作的关键。Microsoft 365 for Mac&#xff08;前身为Office 365&#xff09;是微软为Mac操作系统推出的一套全面的办公软件解决方案&#xff0c;为用户提供了强大的工具和功能&#xff0c;帮助您在任何地方都…

OData服务的开发-SAP Gateway Service Builder Projects

文章目录 概述操作 概述 有多种方法可以开发 OData 服务。对于经典的 ABAP 开发&#xff0c;引入了 SAP Gateway Service Builder。但是&#xff0c;在 SAP S/4HANA 1909 中引入的 ABAP RESTful 应用程序编程模型。 两个模型可以并行使用。但是&#xff0c;建议使用 ABAP RES…

MIT_线性代数笔记:第 10 讲 四个基本子空间

目录 四个子空间 Four subspaces基和维数 Basis& Dimension新向量空间 New vector space 本讲讨论矩阵的四个基本子空间以及他们之间的关系。 四个子空间 Four subspaces 任意的 m x n 矩阵 A 都定义了四个子空间。 列空间 Column space C(A) 矩阵 A 的列空间是 A 的列向…

YOLO改进系列之ParNetAttention注意力机制

ParNet注意力是一种用于自然语言处理任务的注意力机制&#xff0c;它是由谷歌在2019年提出的。ParNet注意力旨在解决传统注意力机制在处理长序列时的效率问题。传统的注意力机制在计算注意力权重时&#xff0c;需要对所有输入序列的位置进行逐一计算&#xff0c;这导致了在长序…

INA219电流感应芯片_程序代码

详细跳转借鉴链接INA219例程此处进行总结 简单介绍一下 INA219&#xff1a; 1、 输入脚电压可以从 0V~26V,INA219 采用 3.3V/5V 供电. 2、 能够检测电流&#xff0c;电压和功率&#xff0c;INA219 内置基准器和乘法器使之能够直接以 A 为单位 读出电流值。 3、 16 位可编程地…

GPT-4 惨遭削弱;拼多多市值一度超阿里;雷军回应个人向武汉大学捐款 13 亿元丨 RTE 开发者日报 Vol.96

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有…

【Openstack Train安装】三、openstack安装

本文在所有节点安装openstack包&#xff0c;请确保按照以下教程完成了相关配置&#xff1a; 【Openstack Train安装】一、虚拟机创建 【Openstack Train安装】二、NTP安装 安装环境如下 VMware WorkstationV17.0本机系统win11虚拟机系统CentOS 7.5 openstack包含多个版本&…

传智杯第五届题解

B.莲子的机械动力学 分析&#xff1a;这题有个小坑&#xff0c;如果是00 0&#xff0c;结果记得要输出0。 得到的教训是&#xff0c;避免前导0出现时&#xff0c;要注意答案为0的情况。否则有可能会没有输出 #include<assert.h> #include<cstdio> #include<…

【神印王座】永恒之塔秘密透露,林鑫告白李馨,皓晨采儿甜蜜接吻

Hello,小伙伴们&#xff0c;我是拾荒君。 《神印王座》第83集如期而至&#xff0c;带来了令人期待已久的更新。与众多热情的观众一样&#xff0c;拾荒君一得到更新消息&#xff0c;便急不可耐地观赏起来。这一集中&#xff0c;龙皓晨随着月魔宫的月夜商队成功抵达联盟&#xf…

下载并安装anaconda和VScode,配置虚拟环境,并使用VScode运行代码

文章目录 前言软件下载Anaconda下载VScode下载 软件安装Anaconda安装Vscod安装 配置虚拟环境并运行代码Anaconda创建环境VScode使用&#xff0c;运行代码1. 打开代码所在文件夹2. 选择解释器3. 运行代码 总结 前言 运行python代码&#xff0c;需要2个软件如下&#xff1a; Ana…

漏洞扫描服务是什么

漏洞扫描服务是维护网络安全的重要一环。通过定期或实时的漏洞扫描&#xff0c;组织可以及时发现并修复可能存在的安全威胁&#xff0c;增强自身网络的安全性。在选择漏洞扫描服务时&#xff0c;需要明确自身的需求和目标&#xff0c;并选择合适的工具和服务提供商。只有这样&a…

TFIDF、BM25、编辑距离、倒排索引

TFIDF TF刻画了词语t对某篇文档的重要性&#xff0c;IDF刻画了词语t对整个文档集的重要性

MySQL数据库如何应对故障恢复与数据恢复回滚

一个最基本的数据库&#xff0c;应当可以做到以下几点 数据持久化&#xff0c;可以将数据保存到磁盘&#xff0c;服务重启数据依然存在。 可以按照某种关系存储数据&#xff0c;如果你用过IO流&#xff0c;那么你会发现整理数据也是一件复杂的事情。我是该追加写呢还是找到某条…

一文讲清楚Python流程控制语句

流程控制就是控制程序如何执行的方法&#xff0c;它适用于任何一门编程语言&#xff0c;其作用在于可以根据用户的需求决定程序执行的顺序。计算机在运行程序时有三种执行方法&#xff1a;第一种是顺序执行&#xff0c;自上而下顺序执行所有的语句&#xff0c;对应程序设计中的…

客户案例:EDLP助力金融行业打造高效数据防泄露体系

客户背景 某金融机构是一家以金融科技为核心&#xff0c;致力于为客户提供全方位、智能化、便捷化金融服务的综合性企业。公司总部位于南京&#xff0c;业务范围覆盖全国&#xff0c;拥有强大的技术研发团队和优秀的业务精英&#xff0c;为客户提供全方位的金融服务解决方案。 …

“最甜港姐”走的与众不同之路

网络图片 媒体最新报道&#xff0c;她被誉为“最甜港姐”&#xff0c;曾是TVB炙手可热的当红花旦&#xff0c;却在最当红的时候选择急流勇退。 她不是退圈去相夫教子&#xff0c;而是读书深造&#xff0c;成为一名专业律师。 前不久&#xff0c;又有消息传出&#xff0c;明年…

06_MySQL数据库高可用解决方案(MHA)

各位道友好&#xff0c;鼠鼠我呀校招刚通过了移动的面试 &#xff0c;但是安排的岗位是偏远县城里面的岗位&#xff0c;各位能给给建议吗&#xff1f;鼠鼠我啊真不想有时候变成销售员去卖产品&#xff01;&#xff01;&#xff01; 任务背景 一、真实案例 公司现在需要做MySQ…

docker集群的详解以及超详细搭建

文章目录 一、问题引入1. 多容器位于同一主机2. 多容器位于不同主机 二、介绍三、特性四、概念1. 节点nodes2. 服务(service)和任务(task)3. 负载均衡 五、docker网络1. overlay网络 六、docker集群搭建1. 环境介绍2. 创建集群3. 集群网络4. 加入工作节点 七、部署可视化界面po…

Python多线程优化:提升程序性能的实例

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python多线程优化&#xff1a;提升程序性能的实例&#xff0c;全文5600字&#xff0c;阅读大约16钟。 多线程是一种有效的并发编程方式&#xff0c;能够提高程序的性能。本文…

基于Java SSM框架实现KTV点歌系统项目【项目源码+论文说明】

基于java的SSM框架实现KTV点歌系统演示 摘要 本论文主要论述了如何使用JAVA语言开发一个KTV点歌系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述KTV点歌系…