LeetCode——218. 天际线问题[The Skyline Problem][困难]——分析及代码[Java]

  • 一、题目
  • 二、分析及代码
    • 1. 扫描线 + 优先队列
      • (1)思路
      • (2)代码
      • (3)结果
  • 三、其他

一、题目

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

每个建筑物的几何信息由数组 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:

输入: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]]

示例 2:

输入:buildings = [[0,2,3],[2,5,3]]
输出:[[0,3],[5,0]]

提示:

  • 1 <= buildings.length <= 10^4
  • 0 <= lefti < righti <= 2^31 - 1
  • 1 <= heighti <= 2^31 - 1
  • buildings 按 lefti 非递减排序

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/the-skyline-problem
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、分析及代码

1. 扫描线 + 优先队列

(1)思路

根据题意,天际线的关键点一定位于建筑的边缘,因此可先提取建筑的所有边缘位置,并按坐标进行排序。
在此基础上,设计一个扫描线从左至右扫描各个边缘位置,获得该处最高建筑的高度,即天际线的高度。
为快速获得各处的最高建筑,可设计一个优先队列,将该处建筑按高度从高到低进行排序。因为题中建筑已按左边缘排序,根据当前位置情况依次入队出队即可。

(2)代码

class Solution {public List<List<Integer>> getSkyline(int[][] buildings) {int n = buildings.length, m = n << 1;//建筑个数,边缘个数List<List<Integer>> ans = new ArrayList<List<Integer>>();//输出答案int[] boundaries = new int[m];//边缘位置for (int i = 0; i < n; i++) {boundaries[i << 1] = buildings[i][0];boundaries[(i << 1) + 1] = buildings[i][1];}Arrays.sort(boundaries);//将建筑的边缘位置按坐标从小到大排序PriorityQueue<int[]> pq = new PriorityQueue<int[]>((a, b) -> b[1] - a[1]);//优先队列,a[0]为建筑右边界,a[1]为建筑高度,按高度从大到小排序int building = 0;//已入队建筑数量for (int i = 0; i < m; i++) {//遍历各个建筑边缘的位置if (i > 0 && boundaries[i - 1] == boundaries[i])//直接跳过重复的边缘位置continue;while (building < n && buildings[building][0] <= boundaries[i])//建筑已按左边缘排序,因此可将左边缘位于当前位置左侧的建筑依次入队pq.offer(new int[]{buildings[building][1], buildings[building++][2]});while (!pq.isEmpty() && pq.peek()[0] <= boundaries[i])//延迟删除队首范围已超出当前边缘位置的建筑pq.poll();int height = (pq.isEmpty()) ? 0 : pq.peek()[1];//空队列对应当前位置天际线高度为0if (ans.size() == 0 || height != ans.get(ans.size() - 1).get(1))//筛除连续相同高度的水平线ans.add(Arrays.asList(boundaries[i], height));}return ans;}
}

(3)结果

执行用时 :11 ms,在所有 Java 提交中击败了 86.44% 的用户;
内存消耗 :41.5 MB,在所有 Java 提交中击败了 73.53% 的用户。

三、其他

暂无。

LeetCode——218. 天际线问题(The Skyline Problem)[困难]——分析及代码(Java)相关推荐

  1. LeetCode——517. 超级洗衣机(Super Washing Machines)[困难]——分析及代码(C++)

    LeetCode--517. 超级洗衣机[Super Washing Machines][困难]--分析及代码[C++] 一.题目 二.分析及代码 1. 贪心 (1)思路 (2)代码 (3)结果 三. ...

  2. LeetCode——552. 学生出勤记录 II(Student Attendance Record II)[困难]——分析及代码(Java)

    LeetCode--552. 学生出勤记录 II[Student Attendance Record II][困难]--分析及代码[Java] 一.题目 二.分析及代码 1. 动态规划 (1)思路 ( ...

  3. LeetCode——1803. 统计异或值在范围内的数对有多少(Count Pairs With XOR in a Range)[困难]——分析及代码(Java)

    LeetCode--1803. 统计异或值在范围内的数对有多少[Count Pairs With XOR in a Range][困难]--分析及代码[Java] 一.题目 二.分析及代码 1. 暴力 ...

  4. Java实现 LeetCode 218 天际线问题

    218. 天际线问题 城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓.现在,假设您获得了城市风光照片(图A)上显示的所有建筑物的位置和高度,请编写一个程序以输出由这些建筑物形成的天际线 ...

  5. [Swift]LeetCode218. 天际线问题 | The Skyline Problem

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblog ...

  6. LeetCode 218. 天际线问题(multiset优先队列)*

    文章目录 1. 题目 2. 解题 1. 题目 城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓. 现在,假设您获得了城市风光照片(图A)上显示的所有建筑物的位置和高度,请编写一个程序以输 ...

  7. LeetCode 218. 天际线问题(C++)*

    思路:优先队列+遍历 1.对于左端点:左端点且高度最高的那个就是左边缘: 2.对于右端点:首先右端点不可能是右边界;如果被删除的右端点是最高的,只有删除最高右端点后,该横坐标处的最高点才会是右边界: ...

  8. leetcode 218. 天际线问题

    城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓.给你所有建筑物的位置和高度,请返回由这些建筑物形成的 天际线 . 每个建筑物的几何信息由数组 buildings 表示,其中三元组 bu ...

  9. Leetcode 218.天际线问题

    天际线问题 城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓.现在,假设您获得了城市风光照片(图A)上显示的所有建筑物的位置和高度,请编写一个程序以输出由这些建筑物形成的天际线(图B). ...

最新文章

  1. [翻译]Joomla 1.5架构(十一) model 包
  2. 哈哈,做个广告,宁波要租房的朋友进来看看
  3. laravel框架中文手册_laravel请求参数校验方法
  4. Android之提示This version of Android Studio cannot open this project, please retry with Android Studio
  5. 字符串处理 —— 回文串相关 —— Manacher 算法
  6. python 运算符重载_Python中类的运算符重载
  7. request.params 用法
  8. 内网穿透工具_utools让你3步搭建一个内网穿透工具
  9. springmvc请求参数获取的几种方法
  10. linux下查看已经安装的jdk 并卸载jdk的方法
  11. 【数据分析】数据分析达人赛3:汽车产品聚类分析
  12. 为什么倡导企业使用电子招投标?
  13. 802.11无线WIFI协议学习笔记(一)
  14. C++基础入门(从了解C++到Hello World)
  15. Warning: componentWillMount has been renamed, and is not recommended for use
  16. Android 禁止安装没有授权的第三方应用
  17. 数据到手了,第一件事先干啥?| 说人话的统计学
  18. 避免毛孩过胖引发健康问题 机器人帮你逗毛孩让他动起来!
  19. InfoPath + Workflow + MOSS
  20. SSO和Oauth2的区别

热门文章

  1. Mathematica与流体力学
  2. 合并报表怎么做快速简单?
  3. PCB中的阻焊和阻焊层是什么?如何区分?
  4. Refused to apply style from ‘http://localhost:63342/.../user.css‘ because its MIME type(‘text/html‘)
  5. 【笔试题】嵌入式软件开发:笔试总结
  6. Linux下实现Freertos模拟器
  7. PE病毒学习笔记——初识感染技术 (转自看雪学院)
  8. ARMv8架构下修改Linux内核并打开kvm硬件虚拟化支持(平台Firefly-rk3568)
  9. 2021-2027全球与中国可打印的RFID标签市场现状及未来发展趋势
  10. 大家能推荐个好用的日程、任务、待办管理app吗?