LeetCode218. The Skyline Problem
https://leetcode.com/problems/the-skyline-problem/description/
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings collectively (Figure B).

The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.
For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .
The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour.
For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].
Notes:
- The number of buildings in any input list is guaranteed to be in the range
[0, 10000]. - The input list is already sorted in ascending order by the left x position
Li. - The output list must be sorted by the x position.
- There must be no consecutive horizontal lines of equal height in the output skyline. For instance,
[...[2 3], [4 5], [7 5], [11 5], [12 7]...]is not acceptable; the three lines of height 5 should be merged into one in the final output as such:[...[2 3], [4 5], [12 7], ...]
思路
比较经典的一题,题目太长完全不需要全部看,直接看两张图以及输入输出就知道题目要干啥了。
看了解析https://briangordon.github.io/2014/08/the-skyline-problem.html,从矩形的左右边入手,将左边和右边在x轴上的点作为critical point,然后:
for each critical point c
c.y gets the height of the tallest rectangle over c

要做的是确定cirtical point的高度。在遍历这些critical point时,通过一个堆来得知 over current critical point c的所有矩形的最高高度,更新critical point的高度。堆顶是最高的点,如果没被移出则表明这个最高的矩形还没结束。对于矩形的左顶点,将其加入堆中,对于右顶点,找出堆中其相应的左顶点并移除它,也就是说在我们从左往右遍历critical point时这个矩形已经结束了。具体代码中,为了在排序后的顶点列表中区分左右顶点,左顶点的值是负数,而右顶点值则存的是正数。
堆中先加入一个零点高度,帮助我们在只有最矮的建筑物时选择最低值。
int[][] buildings, 矩形被存储了一个二维数组,每一行是一个矩形,有3个值,分别是矩形的底在x轴上的左边的点和右边的点,以及矩形的高度,比如[2 9 10]
int[] height, 用于记录critical point所在边的高度,只有两个值,分别是x轴坐标和高度,比如height[0]=1,height[1]=4,表示在x轴为1处的边其高为4
public class Solution {
public List<int[]> getSkyline(int[][] buildings) {
List<int[]> result = new ArrayList<>();
List<int[]> height = new ArrayList<>();
// 拆解矩形,构建顶点的列表
for(int[] b:buildings) {
// 左顶点存为负数
height.add(new int[]{b[0], -b[2]});
// 右顶点存为正数
height.add(new int[]{b[1], b[2]});
}
// 根据横坐标对列表排序,相同横坐标的点纵坐标小的排在前面
Collections.sort(height, new Comparator<int[]>(){
public int compare(int[] a, int[] b){
if(a[0] != b[0]){
return a[0] - b[0];
} else {
return a[1] - b[1];
}
}
});
// 构建堆,按照纵坐标来判断大小
Queue<Integer> pq = new PriorityQueue<Integer>(new Comparator<Integer>(){
public int compare(Integer i1, Integer i2){
return i2 - i1;
}
});
// 将地平线值0先加入堆中
pq.offer(0);
// prev用于记录上次keypoint的高度
int prev = 0;
for(int[] h:height) {
// 将左顶点加入堆中
if(h[1] < 0) {
pq.offer(-h[1]);
} else {
// 将右顶点对应的左顶点移去
pq.remove(h[1]);
}
int cur = pq.peek();
// 如果堆的新顶部和上个keypoint高度不一样,则加入一个新的keypoint
if(prev != cur) {
result.add(new int[]{h[0], cur});
prev = cur;
}
}
return result;
}
}
参考:https://segmentfault.com/a/1190000003786782
注意上面比较器和用PriorityQueue来实现堆数据结构,比较器在java 1.8中还可以通过Lambda表达式来实现,简洁很多。
LeetCode218. The Skyline Problem的更多相关文章
- [Swift]LeetCode218. 天际线问题 | The Skyline Problem
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- [LeetCode] The Skyline Problem 天际线问题
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- [LeetCode] The Skyline Problem
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- The Skyline Problem
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- [LeetCode#218] The Skyline Problem
Problem: A city's skyline is the outer contour of the silhouette formed by all the buildings in that ...
- [LeetCode] 281. The Skyline Problem 天际线问题
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- [LeetCode] 218. The Skyline Problem 天际线问题
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- Java for LeetCode 218 The Skyline Problem【HARD】
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- UVa 105 - The Skyline Problem(利用判断,在于想法)
题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...
随机推荐
- POJ.1552 Doubles(水)
POJ.1552 Doubles(水) 题意分析 暴力 代码总览 #include <cstdio> #include <stdio.h> #define nmax 100 u ...
- ACE反应器(Reactor)模式(4)
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/18/596012.html 定时器的实现 通过Reactor机制,还可以很容易的实现定时器的功 ...
- JSX 的基本语法规则
JSX 的基本语法规则:遇到 HTML 标签(以 < 开头),就用 HTML 规则解析:遇到代码块(以 { 开头),就用 JavaScript 规则解析
- 洛谷 P2800 又上锁妖塔
https://www.luogu.org/problem/show?pid=2800 题目背景 小D在X星买完了想要的东西,在飞往下一个目的地的途中,正无聊的他转头看了看身边的小A,发现小A正在玩& ...
- 社会网络分析——Social Network Analysis
什么是社会网络分析,英文social network analysis.现在这个分析越来越时髦,也越来越显现其在社会科学的研究价值.我在2000年的时候受祝建华老师的邀请到香港城市大学作研究,接触到 ...
- ionic@2.0 beta版本安装指南
由于访问npm官方源下载ionic速度缓慢,淘宝提供了npm源,方便国内人士访问. 1.通过config命令 npm config set registry https://registry.npm. ...
- Robot Framework 自定义关键字 Ignore error
以上是关键字的完整写法. 一下是调用该关键字的实例.
- 【51NOD】消灭兔子
[算法]贪心 #include<cstdio> #include<algorithm> #include<cstring> #include<queue> ...
- ...args剩余参数用法
剩余参数语法允许我们将一个不定数量的参数表示为一个数组. function sum(...theArgs) { return theArgs.reduce((previous, current) ...
- jq_常用方法
//获取兄弟元素 $('.class').siblings() 当前元素所有的兄弟节点 $('.class').prev() 当前元素前一个兄弟节点 $('.class').prevaAll() 当前 ...