Lintcode131 Building Outline solution 题解

【题目描述】

GivenNbuildings in a x-axis,each building is a rectangle and can be represented by a triple (start, end, height),where start is the start position on x-axis, end is the end position on x-axis and height is the height of the building. Buildings may overlap if you see them from far away,find the outline of them。


Lintcode131 Building Outline solution 题解_第1张图片

Notice

Please merge the adjacent outlines if they have the same height and make sure different outlines cant overlap on x-axis.

在x轴的n个建筑物中,每一个建筑物都是矩形,可以用三个量(开始,结束,高度)来表示,其中开始是x轴的起始位置,末端是x轴的结束位置,高度是建筑物的高度。如果你从很远的地方看,找它们的轮廓,你可能会看到建筑物重叠。

【注】:一个轮廓可以用三个量(开始,结束,高度)来表示,其中起始是轮廓的x轴的起始位置,末端是x轴的结束位置,高度是轮廓的高度。

【题目链接】

www.lintcode.com/zh-cn/problem/building-outline/

【题目解析】

用一个带最大堆的扫描线遍历数组,每出现一个拐点则记录一次区间。新加入一个元素后若堆顶元素和之前不同,则表明出现拐点。

首先处理数组中元素。将每一个点用一个point来保存,保存time(开始写错了,应该是位置,但是要改的太多了),flag(起点为1,终点为0),height。用一个HashMap来记录每一对终点和起点(终点为key,起点为value)。

将所有point保存在一个list中并排序,首先根据时间从小到大排序,若时间相等则根据flag排序(先起点后终点),若flag也相等则根据height排序(若同为起点则从大到小排序,若同为终点则从小到大排序)。这样可以避免重复解。

再构建一个最大堆,用于记录加入的元素的最大值。

开始遍历list中每个point,起点元素加入堆,终点元素删去堆中对应的起点元素。

当遇到一个起点元素时,先记录加入前堆顶元素,然后将该起点元素加入,再看加入后堆顶元素,1)若没有变化,则继续下一个point;2)若有变化,则说明出现拐点,将之前堆顶元素时间作为起点,当前堆顶元素时间作为终点,之前堆顶元素高度作为高度。注意:就算堆顶元素变化,但是如果之前堆顶元素和当前堆顶元素时间相同,说明是在这个时间连续有几个起点被加入,宽度为0,不能算一个区间。

当遇到一个终点元素时,将其对应的起点元素从堆中删除。若此时堆为空,则和5中一样记录一个区间,并继续下一个point。若堆不为空,则需要看此时堆顶元素是否改变。若不变则继续,否则说明出现“拐点”。此处“拐点”要分两种情况讨论: 1)若新的堆顶元素高度和之前堆顶元素高度相同,则说明相同高度的两段区间有重叠,题目要求若发生这种情况要合并这两段区间,所以我们要保留之前的堆顶元素(两段同高度相同重叠区间的最左边),删去新的堆顶元素(即代替原堆顶元素被删除,因为每遇到一个终点必须删去一个起点),具体做法可以是先删去新堆顶元素,再加入原堆顶元素,或者直接将新堆顶元素时间改为原堆顶元素时间。 2)若新堆顶和原堆顶元素高度不同,则像5中那样记录一个区间,但是要将现在的堆顶元素时间改为遇到的终点元素的时间。

遍历完整个list结束

【参考答案】

www.jiuzhang.com/solutions/building-outline/

你可能感兴趣的:(Lintcode131 Building Outline solution 题解)