LC 1840. 最高建筑高度
https://leetcode-cn.com/problems/maximum-building-height/
其实这题我也不知道怎么搞的,而且我也没有办法证明算法正确。
直觉上就是遍历并且更新每个点上的约束。如果某个点最大高度变化的话,那么可能需要返回去遍历之前点的约束。不过如果这样做的话,那么时间复杂度就会比较高。
换个想法,某个点的最大高度只可能不断减小,随着后面遍历这个上限会不断下降。所以索性我们就不返回约束之前的节点了,而是前序遍历完成之后,再反向遍历去更新约束。
直觉上可以解释为,如果这个约束是单调的话(最大高度只能是递减),那么前后两遍遍历应该是正确的。最后最大高度会处于两个有约束的楼栋之间,这个用个简单公式就可以计算出来。
#!/usr/bin/env python3
# coding:utf-8
# Copyright (C) dirlt
from typing import List
from collections import Counter, defaultdict, deque
from functools import lru_cache
import heapq
class Solution:
def maxBuilding(self, n: int, restrictions: List[List[int]]) -> int:
if not restrictions: return n-1
restrictions.append((1, 0))
restrictions.sort(key = lambda x: x[0])
for i in range(1, len(restrictions)):
(a, ha) = restrictions[i-1]
(b, hb) = restrictions[i]
d = (b - a)
if hb > (ha + d):
restrictions[i] = (b, ha + d)
for i in reversed(range(len(restrictions) - 1)):
(a, ha) = restrictions[i]
(b, hb) = restrictions[i+1]
d = (b - a)
if ha > (hb + d):
restrictions[i] = (a, hb + d)
print(restrictions)
ans = 0
for i in range(1, len(restrictions)):
(a, ha) = restrictions[i-1]
(b, hb) = restrictions[i]
d = b - a
x = (hb - ha + d) // 2
maxh = ha + x
# print('({}, {}) & ({}, {}) = {}'.format(a, ha, b, hb, maxh))
ans = max(ans, maxh)
ans = max(ans, n - restrictions[-1][0] + restrictions[-1][1])
return ans