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。


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/





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值