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 ...
随机推荐
- 洛谷 P4735 最大异或和 解题报告
P4735 最大异或和 题目描述 给定一个非负整数序列\(\{a\}\),初始长度为\(N\). 有\(M\)个操作,有以下两种操作类型: A x:添加操作,表示在序列末尾添加一个数\(x\),序列的 ...
- javascript push 和 concat 的区别
array.push(item1,item2,item3...) array.concat(item1,item2,item3...) 1. push和concat的元素都既可以是普通元素(任意类型) ...
- could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5 or one of(maven报错)
could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.5 or one of ...
- dubbo在项目中的应用
关于dubbo的使用,我们举个简单例子: 存在2个系统,A系统和B系统,A系统调用B系统的接口获取数据,用于查询用户列表. 在上一篇博文介绍了dubbo的创建,zookeeper的创建完成后,我们可以 ...
- C#学习目录处理
目录获取和处理: string path = ".";//表明要在当前所在的目录 //先定义目录信息变量 DirectoryInfo dir = new DirectoryInfo ...
- sudo 的配置详解
从编写 sudo 配置文件/etc/sudoers开始: sudo的配置文件是/etc/sudoers ,我们可以用他的专用编辑工具visodu ,此工具的好处是在添加规则不太准确时,保存退出时会提示 ...
- SSH 指定密钥,连接远程服务器。
ssh -i /root/.ssh/private.pem user@192.168.1.100 -p 7744 如上, /root/.ssh/private.pem :密钥文件路径user@192. ...
- Java设计模式の工厂模式
-------------------------------------------------------- 目录: 一.序言 二.简单工厂模式 三.工厂方法模式 四.简单工厂和工厂方法模式的比 ...
- Java中主线程如何捕获子线程抛出的异常
首先明确线程代码的边界.其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界.Runnable接口中run方法原型如下: public void run(); 而所有的具 ...
- HDU 5961 传递 BFS
题意:中文题,就是判断一个竞赛图拆成两个图,判断是否都传递 思路:分别BFS判深度即可,用这种方法注意要进行读入优化. /** @Date : 2016-11-18-20.00 * @Author : ...