此题比较简单,直接扫描线法处理就可以了。先把每个楼的三元组 (left, height, right) 转化为两个事件:left 转化为进入事件,right 转化为离开事件。然后对所有的事件进行排序后从左向右进行扫描处理:
- 一个楼进入扫描线:加入到“活动楼列表”,如果其 height > currentSkylineHeight,则修改 currentSkylineHeight 为 height
- 一个楼离开扫描线:从“活动楼列表”删除之,如果其 height == currentSkylineHeight,则在“活动楼列表”中找到最高的一个,若最高的那一个的 height’ < currrentSkylineHeight,调整currentSkylineHeight 为 height’
要注意的点有几个:
- 在一个 x 坐标处可能有多个楼进入,多个楼离开。要先处理进入的,再处理离开的。这可以在排序时定好规则。
- 处理进入的楼时,要一次把所有在同一个 x 坐标处进入的楼全部扫描完,找到其中最高的高度与当前 skyline 的高度比较。一个 x 坐标处最多变化一次。
- 处理离开的楼时,也与上面一样,注意一个 x 坐标处最多变化一次
- 如果要在线提交得到AC,输出完成后必须加上个回车(我为此WA了很多次。。。)
扫描线在处理这种线段或是面积之类的问题时经常用到,多练习会对处理这类问题很有帮助。