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 天际线问题的更多相关文章

  1. 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 ...

  2. Leetcode 218.天际线问题

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

  3. 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 ...

  4. 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. ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. [hdu4497]分解质因数

    题意:求满足gcd(x,y,z)=G,lcm(x,y,z)=L的x,y,z的解的个数. 大致思路:首先如果L % G != 0那么无解,否则令u = L / G,问题变为,gcd(r,s,t)=1,l ...

  2. java 实现仿照微信抢红包算法,实测结果基本和微信吻合,附demo

    实现拼手气红包算法,有以下几个需要注意的地方: 抢红包的期望收益应与先后顺序无关 保证每个用户至少能抢到一个预设的最小金额,人民币红包设置的最小金额一般是0.01元,如果需要发其他货币类型的红包,比如 ...

  3. java套打

    1:套打可能是以后软件开发可能会涉及到的功能,主要麻烦地方就是需要精确定位,光是打印发票还好,要是打印那种协议类型的特别麻烦,不仅长而且需要的数据多 ,定位麻烦. 2:而且大多数情况是需要去除页眉页脚 ...

  4. 【雕爷学编程】Arduino动手做(49)---有源蜂鸣器模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...

  5. SpringBoot注解分析

    Spring boot 简介:是spring社区发布的一个开源项目,旨在帮助开发者更快更简单的构建项目,使用习惯优于配置,的理念让你的项目快速的跑起来,使用springboot可以不用,或者很少的配置 ...

  6. 5.7 Go 捕获异常

    5.7 Go 捕获异常 Go语言处理异常不同于其他语言处理异常的方式. 传统语言处理异常: try catch finally go语言 引入了defer.panic.recover 1.Go程序抛出 ...

  7. Django之form表单常用字段与插件

    from django.shortcuts import render,HttpResponse from django import forms from app01 import models f ...

  8. 使用基于MVC2模式创建新闻网站

    1.什么是MVC MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示 ...

  9. 王艳 201771010127《面向对象程序设计(java)》第十七周学习总结

    实验十七  线程同步控制 实验时间 2018-12-10 一.理论部分 1.线程同步:多线程并发运行不确定性问题解决方案:引入线程同步机制,使得另一线程要使用该方法,就只能等待. 解决方案: 1)锁对 ...

  10. 201771010128 王玉兰《面象对象程序设计 (Java) 》第六周学习总结

    ---恢复内容开始--- 第一部分:基础知识总结: 1.继承 A:用已有类来构建新类的一种机制,当定义了一个新类继承一个类时,这个新类就继承了这个类的方法和域以适应新的情况: B:特点:具有层次结构. ...