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


Buildings Skyline Contour
每个建筑物的几何信息用三元组 [Li,Ri,Hi] 表示,其中 Li 和 Ri 分别是第 i 座建筑物左右边缘的 x 坐标,Hi 是其高度。可以保证 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX 和 Ri - Li > 0。您可以假设所有建筑物都是在绝对平坦且高度为 0 的表面上的完美矩形。
例如,图A中所有建筑物的尺寸记录为:[ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] 。
输出是以 [ [x1,y1], [x2, y2], [x3, y3], … ] 格式的“关键点”(图B中的红点)的列表,它们唯一地定义了天际线。关键点是水平线段的左端点。请注意,最右侧建筑物的最后一个关键点仅用于标记天际线的终点,并始终为零高度。此外,任何两个相邻建筑物之间的地面都应被视为天际线轮廓的一部分。
例如,图B中的天际线应该表示为:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ]。
说明:
任何输入列表中的建筑物数量保证在 [0, 10000] 范围内。
输入列表已经按左 x 坐标 Li 进行升序排列。
输出列表必须按 x 位排序。
输出天际线中不得有连续的相同高度的水平线。例如 […[2 3], [4 5], [7 5], [11 5], [12 7]…] 是不正确的答案;三条高度为 5 的线应该在最终输出中合并为一个:[…[2 3], [4 5], [12 7], …]
class Solution {
// 线段树
public List<List<Integer>> getSkyline(int[][] buildings) {
int len = buildings.length;
if (len == 0) return new ArrayList<>();
return segment(buildings, 0, len - 1);
}
private List<List<Integer>> segment(int[][] buildings, int l, int r) {
// 创建返回值
List<List<Integer>> res = new ArrayList<>();
// 找到树底下的结束条件 -> 一个建筑物
if (l == r) {
res.add(Arrays.asList(buildings[l][0], buildings[l][2])); // 左上端坐标
res.add(Arrays.asList(buildings[l][1], 0)); // 右下端坐标
return res;
}
int mid = l + (r - l) / 2; // 取中间值
// 左边递归
List<List<Integer>> left = segment(buildings, l, mid);
// 右边递归
List<List<Integer>> right = segment(buildings, mid + 1, r);
// 左右合并
// 创建left 和 right 的索引位置
int m = 0, n = 0;
// 创建left 和 right 目前的高度
int lpreH = 0, rpreH = 0;
// 两个坐标
int leftX, leftY, rightX, rightY;
while (m < left.size() || n < right.size()) {
// 当有一边完全加入到res时,则加入剩余的那部分
if (m >= left.size()) res.add(right.get(n++));
else if (n >= right.size()) res.add(left.get(m++));
else { // 开始判断left 和 right
leftX = left.get(m).get(0); // 不会出现null,可以直接用int类型
leftY = left.get(m).get(1);
rightX = right.get(n).get(0);
rightY = right.get(n).get(1);
//看我这两个矩形谁靠左
if (leftX < rightX) {
//左面还比以前高,就加左面
if (leftY > rpreH) res.add(left.get(m));
//左面比右面高,我要加入左面点的以及以前右面的的高度,因为我马上就有新高度了2,10
else if (lpreH > rpreH) res.add(Arrays.asList(leftX, rpreH));
// 用我左面的高替换我以前右面的高
lpreH = leftY;
m++;
} else if (leftX > rightX) {
if (rightY > lpreH) res.add(right.get(n));
else if (rpreH > lpreH) res.add(Arrays.asList(rightX, lpreH));
rpreH = rightY;
n++;
} else { // left 和 right 的横坐标相等
if (leftY >= rightY && leftY != (lpreH > rpreH ? lpreH : rpreH)) res.add(left.get(m));
else if (leftY <= rightY && rightY != (lpreH > rpreH ? lpreH : rpreH)) res.add(right.get(n));
lpreH = leftY;
rpreH = rightY;
m++;
n++;
}
}
}
return res;
}
}
Java实现 LeetCode 218 天际线问题的更多相关文章
- 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 ...
- Leetcode 218.天际线问题
天际线问题 城市的天际线是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓.现在,假设您获得了城市风光照片(图A)上显示的所有建筑物的位置和高度,请编写一个程序以输出由这些建筑物形成的天际线(图B). ...
- Java for LeetCode 216 Combination Sum III
Find all possible combinations of k numbers that add up to a number n, given that only numbers from ...
- Java for LeetCode 214 Shortest Palindrome
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. ...
- Java for LeetCode 212 Word Search II
Given a 2D board and a list of words from the dictionary, find all words in the board. Each word mus ...
- Java for LeetCode 211 Add and Search Word - Data structure design
Design a data structure that supports the following two operations: void addWord(word)bool search(wo ...
- Java for LeetCode 210 Course Schedule II
There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...
- Java for LeetCode 200 Number of Islands
Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...
- Java for LeetCode 188 Best Time to Buy and Sell Stock IV【HARD】
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
随机推荐
- SQL注入和Mybatis预编译防止SQL注入
什么是SQL注入?? 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或页面请求url的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序,将(恶意)的SQL命 ...
- vue mock 模拟接口数据
日常总结 希望能帮到大家 1 mock/sever.js //创建服务 let http=require('http') let fs=require('fs') let url=require(' ...
- 单线程和多线程执行对比—Python多线程编程
单线程和多线程执行对比 本章使用递归求斐波那契.阶乘与累加函数的执行来对比单线程与多线程: 斐波那契.阶乘与累加(mtfacfib.py): import threading from time ...
- HDU 2006 (水)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2006 题目大意:给你几个数,求奇数的乘积和 解题思路: 很水,不需要数组的,一个变量 x 就行 代码: ...
- Mysql 常用函数(3)- ifnull 函数
Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html ifnull 的作用 可以判断某个字段的值是否为 ...
- Universalimageloader 原图片大小获取
Universalimageloader1.9.5上还没有对外提供获取图片的原大小功能,如果需要获取图片的源大小,可参考stackoverflow上的解决办法 stackoverflow地址 主要实现 ...
- Spring-mvc 配置文件applicationContext.xml
相关jar包(4.3.16.RELEASE) <!-- Spring mvc 基础jar包,maven 依赖 --> <dependency> <groupId>o ...
- 学会阅读源码后,我觉得自己better了
我有一个大学同学,名叫石磊,我在之前的文章里提到过几次,我们俩合作过很多项目.只要有他在,我就特别放心,因为几乎所有难搞的问题,到他这,都能够巧妙地化解.他给我印象最深刻的一句话就是,"有啥 ...
- RobotFramework自动化测试之元素定位
前言:最近在做基于RF框架的Web自动化测试,其中涉及到元素的定位,主要用到id.name.xpath.css四中定位方法,尤其后面的两种方法特别有效,可以解决大部分的定位问题. id和name定位 ...
- Redux:data flow
我们使用react,是为了构建可复用的高性能的视图层,学习redux是为了处理视图组件中随应用复杂度提升而变得难以控制的state.说白了,是为了视图. 在了解了action.reducer和stor ...