解法
一开始打算加一个建筑改一次,果然肯定是错的
观察图可以发现,假设这个图是从左向右推进的,坐标为
i
i
i的时候的高度
H
(
i
)
H(i)
H(i)为:还未结束的矩形的高度的最大值,这个还未结束包括从i开始的矩形,不包括从i结束的矩形。
什么时候把点加到答案里呢?观察可发现,点只可能出现在矩形的边界位置,且当
H
(
i
)
!
=
H
(
i
−
1
)
H(i)!=H(i-1)
H(i)!=H(i−1)的时候,需要加入一个
[
i
,
H
(
i
)
]
[i,H(i)]
[i,H(i)]的点
所以,从左往右扫描边界位置,分析已结束的矩形和没有结束的矩形就可以了
参考:https://www.cnblogs.com/grandyang/p/4534586.html给出的想法,可以把右边界的高度存成负数,既有助于区分起点和终点,又有助于先处理终点。(不过我同一个坐标一次性处理了,好像也不需要优先处理终点……?)
class Solution(object):
def getSkyline(self, buildings):
"""
:type buildings: List[List[int]]
:rtype: List[List[int]]
"""
tmp = []
for i,(l,r,h) in enumerate(buildings):
tmp.append((l,h,i))
tmp.append((r,-h,i))
tmp.sort()
n = len(tmp)
starts = []
res = []
i = 0
while i<n:
old = buildings[starts[0]][2] if len(starts) else 0
while i<n:
x, h, j = tmp[i]
if h<0:
starts.remove(j)
elif len(starts)==0:
starts.append(j)
else:
l = 0
r = len(starts)
while r-l>1:
mid = (l+r)>>1
if h<=buildings[starts[mid]][2]:
l = mid
else:
r = mid
if h<=buildings[starts[l]][2]:
starts.insert(l+1, j)
else:
starts.insert(l,j)
if i+1>=n or tmp[i+1][0]!=tmp[i][0]:
break
else:
i += 1
if len(starts) and buildings[starts[0]][2] != old:
res.append([tmp[i][0], buildings[starts[0]][2]])
elif len(starts)==0:
res.append([tmp[i][0],0])
i += 1
return res