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