leetcode 218. 天际线问题

城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度,请返回由这些建筑物形成的 天际线 。

每个建筑物的几何信息由数组 buildings 表示,其中三元组 buildings[i] = [lefti, righti, heighti] 表示:

  • lefti 是第 i 座建筑物左边缘的 x 坐标。
  • righti 是第 i 座建筑物右边缘的 x 坐标。
  • heighti 是第 i 座建筑物的高度。

天际线 应该表示为由 “关键点” 组成的列表,格式 [[x1,y1],[x2,y2],…] ,并按 x 坐标 进行 排序 。关键点是水平线段的左端点。列表中最后一个点是最右侧建筑物的终点,y 坐标始终为 0 ,仅用于标记天际线的终点。此外,任何两个相邻建筑物之间的地面都应被视为天际线轮廓的一部分。

注意:输出天际线中不得有连续的相同高度的水平线。例如 […[2 3], [4 5], [7 5], [11 5], [12 7]…] 是不正确的答案;三条高度为 5 的线应该在最终输出中合并为一个:[…[2 3], [4 5], [12 7], …]

  • 示例 1:

image.png

输入:buildings = [[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]]
输出:[[2,10],[3,15],[7,12],[12,0],[15,10],[20,8],[24,0]]
解释:
图 A 显示输入的所有建筑物的位置和高度,
图 B 显示由这些建筑物形成的天际线。图 B 中的红点表示输出列表中的关键点。
示例 2:输入:buildings = [[0,2,3],[2,5,3]]
输出:[[0,3],[5,0]]

解题思路

通过观察我们可以得出

  • 关键点总是来源于建筑物的左边缘或者右边缘的
  • 相邻两个关键点之间必定存在高度差
    因此,我们可以只对所有建筑物的左右边缘进行遍历,关键点只在这些点当中产生

因为最终结果的关键点需要按照x坐标进行排序,因此我们先对所有建筑物的左右端点按x坐标进行一次统一的从小到大的排序,x坐标相同的话,按高度从小到大的排序

为了区分建筑物的左右端点,我们可以用负数表示左端点的高度,正数表示右端点的高度

假设遍历到某个端点cur,大顶堆中存放的是:该端点处于的x坐标,被若干个建筑物
image.png
例如,x=7时,存储的就是3个建筑物的高度,因为当前遍历的是红色建筑物的右端点,因此在当前x=7的坐标下,已经不被覆盖了,所以是2个建筑物的高度,而这两个建筑物的最大高度是12,和之前关键点的最大高度不一致,因此可以判断出现了关键点

总结

简单来说,在遍历端点的过程中,通过高度的正负来实现对建筑物左右端点的判断,遍历到左端点则进入优先队列,说明后面的若干个x坐标都被当前高度为h的建筑物覆盖,遍历到右端点则退出优先队列,说明后面的所有x坐标都不会被当前高度为h的建筑物覆盖。所以通过优先队列,我们就可以知道,当前的端点的x坐标覆盖了多少个建筑物,因为最高的建筑物会遮盖其他低的建筑物,所以我们维护的是一个大顶堆。

又因为关键点和前一个关键点的高度必然是不一样的,所以只要当前的堆顶元素和前一个关键点的高度不一样,我们就可以判断当前x坐标也是一个关键点

代码

class Solution {public List<List<Integer>> getSkyline(int[][] buildings) {List<List<Integer>> res=new ArrayList<>();List<int[]> cnt=new ArrayList<>();for (int[] building : buildings) {cnt.add(new int[]{building[0],-building[2]});cnt.add(new int[]{building[1],building[2]});}int i=0,pre=0;Collections.sort(cnt,(o1, o2) -> o1[0]==o2[0]?o1[1]-o2[1]:o1[0]-o2[0]);PriorityQueue<Integer>priorityQueue=new PriorityQueue<>((o1, o2) -> o2-o1);priorityQueue.add(0);for (int[] cur : cnt) {if(cur[1]<0){priorityQueue.add(-cur[1]);}else{priorityQueue.remove(cur[1]);}int h=priorityQueue.peek();if(h!=pre){res.add(Arrays.asList(cur[0],h));pre=h;}}return res;}
}

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

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

相关文章

[Android Pro] 终极组件化框架项目方案详解

cp from : https://blog.csdn.net/pochenpiji159/article/details/78660844 前言 本文所讲的组件化案例是基于自己开源的组件化框架项目github上地址github.com/HelloChenJi…其中即时通讯(Chat)模块是单独的项目github上地址github.com/HelloChenJi… 1.什么是组件化&#xff…

如何写一个vue指令directive

举个例子 &#xff1a;clickoutside.js const clickoutsideContext clickoutsideContext;export default {/*param el 指令所绑定的元素param binding {Object} param vnode vue编译生成的虚拟节点*/bind (el, binding, vnode) {const documentHandler function(e) {console.…

安装angular cli_Angular 9适用于初学者—如何使用Angular CLI安装第一个应用程序

安装angular cliAngular is one of the most popular JavaScript frameworks created and developed by Google. In the last couple of years, ReactJS has gained a lot of interest and has become the most popular modern JS library in the industry. But this doesn’t …

leetcode 1818. 绝对差值和

给你两个正整数数组 nums1 和 nums2 &#xff0c;数组的长度都是 n 。 数组 nums1 和 nums2 的 绝对差值和 定义为所有 |nums1[i] - nums2[i]|&#xff08;0 < i < n&#xff09;的 总和&#xff08;下标从 0 开始&#xff09;。 你可以选用 nums1 中的 任意一个 元素来…

【转载】keil5中加入STM32F10X_HD,USE_STDPERIPH_DRIVER的原因

初学STM32&#xff0c;在RealView MDK 环境中使用STM32固件库建立工程时&#xff0c;初学者可能会遇到编译不通过的问题。出现如下警告或错误提示&#xff1a; warning: #223-D: function "assert_param" declared implicitly;assert_param(IS_GPIO_ALL_PERIPH(GPIOx…

下岗职工_下岗后我如何获得多位软件工程师的面试

下岗职工“Opportunities to find our deeper powers come when life seems most challenging.” -Joseph Campbell“当生活似乎最具挑战性时&#xff0c;就有机会找到我们更深层的力量。” 约瑟夫坎贝尔 I was recently laid off for the first time in my life. I realized t…

1846. 减小和重新排列数组后的最大元素

给你一个正整数数组 arr 。请你对 arr 执行一些操作&#xff08;也可以不进行任何操作&#xff09;&#xff0c;使得数组满足以下条件&#xff1a; arr 中 第一个 元素必须为 1 。任意相邻两个元素的差的绝对值 小于等于 1 &#xff0c;也就是说&#xff0c;对于任意的 1 <…

bashdb常用命令

一、列出代码和查询代码类&#xff1a; l 列出当前行以下的10行- 列出正在执行的代码行的前面10行. 回到正在执行的代码行w 列出正在执行的代码行前后的代码/pat/ 向后搜索pat&#xff1f;pat&#xff1f;向前搜索pat二、Debug控制类&#xff1a; h 帮助help 命令 得到…

podcast播客资源_为什么播客是我的新维基百科-完美的非正式学习资源

podcast播客资源In this article, I’ll explain why podcasts replaced a lot of my Wikipedia usage for informal learning. I’ll also talk about how I listen to 5 hours of podcasts every day.在本文中&#xff0c;我将解释为什么播客代替了我的许多Wikipedia用于非正…

剑指 Offer 53 - I. 在排序数组中查找数字 I(二分法)

统计一个数字在排序数组中出现的次数。 示例 1: 输入: nums [5,7,7,8,8,10], target 8 输出: 2 示例 2: 输入: nums [5,7,7,8,8,10], target 6 输出: 0 限制&#xff1a; 0 < 数组长度 < 50000 解题思路 先用二分法查找出其中一个目标元素再向目标元素两边查找…

MVC与三层架构区别

我们平时总是将三层架构与MVC混为一谈&#xff0c;殊不知它俩并不是一个概念。下面我来为大家揭晓我所知道的一些真相。 首先&#xff0c;它俩根本不是一个概念。 三层架构是一个分层式的软件体系架构设计&#xff0c;它可适用于任何一个项目。 MVC是一个设计模式&#xff0c;它…

tensorflow 实现逻辑回归——原以为TensorFlow不擅长做线性回归或者逻辑回归,原来是这么简单哇!...

实现的是预测 低 出生 体重 的 概率。尼克麦克卢尔&#xff08;Nick McClure&#xff09;. TensorFlow机器学习实战指南 (智能系统与技术丛书) (Kindle 位置 1060-1061). Kindle 版本. # Logistic Regression #---------------------------------- # # This function shows ho…

sdlc 瀑布式 生命周期_SDLC指南–软件开发生命周期的阶段和方法

sdlc 瀑布式 生命周期When I decided to teach myself how to code almost four years ago I had never heard of, let alone thought about, the software development life cycle.当我差不多四年前决定教自己如何编码时&#xff0c;我从未听说过软件开发生命周期&#xff0c;…

剑指 Offer 48. 最长不含重复字符的子字符串

请从字符串中找出一个最长的不包含重复字符的子字符串&#xff0c;计算该最长子字符串的长度。 示例 1: 输入: “abcabcbb” 输出: 3 解释: 因为无重复字符的最长子串是 “abc”&#xff0c;所以其长度为 3。 示例 2: 输入: “bbbbb” 输出: 1 解释: 因为无重复字符的最长子…

Mysql-my-innodb-heavy-4G.cnf配置文件注解

Mysql-同Nginx等一样具备多实例的特点&#xff0c;简单的讲就是在一台服务器上同时开启多个不同的服务端口&#xff08;3306,3307&#xff09;同时运行多个Mysql服务进程&#xff0c;这些服务进程通过不同的socket监听不同的服务端口来提供服务。这些Mysql多实例公用一套Mysql安…

is 和 == 的区别

is 和 操作符的区别 python官方解释&#xff1a; 的meaning为equal&#xff1b; is的meaning为object identity&#xff1b; is 判断对象是否相等&#xff0c;即身份是否相同&#xff0c;使用id值判断&#xff1b; 判断对象的值是否相等。id值是什么&#xff1f;id()函数官网…

win10管理凌乱桌面_用于管理凌乱的开源存储库的命令行技巧

win10管理凌乱桌面Effective collaboration, especially in open source software development, starts with effective organization. To make sure that nothing gets missed, the general rule, “one issue, one pull request” is a nice rule of thumb.有效的协作(特别是…

JAVA数组Java StringBuffer 和 StringBuilder 类

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/qq_34173549/article/details/80215173 Java StringBuffer 和 StringBuilder 类 当对字符串进行修改的时候&#xff0c;需要使用 StringBuffer 和 StringBuilder 类。 和 Str…

strlen和sizeof的长度区别

strlen返回字符长度 而sizeof返回整个数组占多长&#xff0c;字符串的\0也会计入一个长度转载于:https://www.cnblogs.com/DawaTech/p/8086055.html

了解如何使用Yii2 PHP框架创建YouTube克隆

Yii is a fast, secure, and efficient PHP framework used to create all kinds of web apps. Weve released a full video course on how to use the Yii2 framework.Yii是一个快速&#xff0c;安全&#xff0c;高效PHP框架&#xff0c;用于创建各种Web应用程序。 我们已经发…