Welcome to Subscribe On Youtube
Formatted question description: https://leetcode.ca/all/1840.html
1840. Maximum Building Height
Level
Hard
Description
You want to build n
new buildings in a city. The new buildings will be built in a line and are labeled from 1
to n
.
However, there are city restrictions on the heights of the new buildings:
- The height of each building must be a non-negative integer.
- The height of the first building must be
0
. - The height difference between any two adjacent buildings cannot exceed
1
.
Additionally, there are city restrictions on the maximum height of specific buildings. These restrictions are given as a 2D integer array restrictions
where restrictions[i] = [id_i, maxHeight_i]
indicates that building id_i
must have a height less than or equal to maxHeight_i
.
It is guaranteed that each building will appear at most once in restrictions
, and building 1
will not be in restrictions
.
Return the maximum possible height of the tallest building.
Example 1:
Input: n = 5, restrictions = [[2,1],[4,1]]
Output: 2
Explanation: The green area in the image indicates the maximum allowed height for each building.
We can build the buildings with heights [0,1,2,1,2], and the tallest building has a height of 2.
Example 2:
Input: n = 6, restrictions = []
Output: 5
Explanation: The green area in the image indicates the maximum allowed height for each building.
We can build the buildings with heights [0,1,2,3,4,5], and the tallest building has a height of 5.
Example 3:
Input: n = 10, restrictions = [[5,3],[2,5],[7,4],[10,3]]
Output: 5
Explanation: The green area in the image indicates the maximum allowed height for each building.
We can build the buildings with heights [0,1,2,3,3,4,4,5,4,3], and the tallest building has a height of 5.
Constraints:
2 <= n <= 10^9
0 <= restrictions.length <= min(n - 1, 10^5)
2 <= id_i <= n
id_i
is unique.0 <= maxHeight_i <= 10^9
Solution
Sort restrictions
according to the id
values. Then loop over restrictions
forward and backward to determine the actual maximum possible height of each element in restrictions
. Next, for two adjacent restrictions [i, a]
and [j, b]
where i < j
, the maximum possible height in the ranges [i, j]
is (j - i + Math.abs(b - a)) / 2 + Math.min(a, b)
. The last thing is to calculate the maximum possible height of the building with id = n
. Finally, return the maximum possible height among all n
buildings.
-
class Solution { public int maxBuilding(int n, int[][] restrictions) { Arrays.sort(restrictions, new Comparator<int[]>() { public int compare(int[] restriction1, int[] restriction2) { return restriction1[0] - restriction2[0]; } }); int maxHeight = 0; int length = restrictions.length; int prevId = 1, prevHeight = 0; for (int i = 0; i < length; i++) { int[] restriction = restrictions[i]; int currId = restriction[0], currHeight = restriction[1]; int difference = currId - prevId; restrictions[i][1] = Math.min(restrictions[i][1], prevHeight + difference); prevId = currId; prevHeight = restrictions[i][1]; } for (int i = length - 2; i >= 0; i--) { int difference = restrictions[i + 1][0] - restrictions[i][0]; restrictions[i][1] = Math.min(restrictions[i][1], restrictions[i + 1][1] + difference); } prevId = 1; prevHeight = 0; for (int i = 0; i < length; i++) { int[] restriction = restrictions[i]; int currId = restriction[0], currHeight = restriction[1]; int difference = currId - prevId; restrictions[i][1] = Math.min(restrictions[i][1], prevHeight + difference); int heightDifference = Math.abs(currHeight - prevHeight); int curMaxHeight = (difference + heightDifference) / 2 + Math.min(prevHeight, currHeight); maxHeight = Math.max(maxHeight, curMaxHeight); prevId = currId; prevHeight = currHeight; } int lastHeight = prevHeight + (n - prevId); maxHeight = Math.max(maxHeight, lastHeight); return maxHeight; } } ############ class Solution { public int maxBuilding(int n, int[][] restrictions) { List<int[]> r = new ArrayList<>(); r.addAll(Arrays.asList(restrictions)); r.add(new int[] {1, 0}); Collections.sort(r, (a, b) -> a[0] - b[0]); if (r.get(r.size() - 1)[0] != n) { r.add(new int[] {n, n - 1}); } int m = r.size(); for (int i = 1; i < m; ++i) { int[] a = r.get(i - 1), b = r.get(i); b[1] = Math.min(b[1], a[1] + b[0] - a[0]); } for (int i = m - 2; i > 0; --i) { int[] a = r.get(i), b = r.get(i + 1); a[1] = Math.min(a[1], b[1] + b[0] - a[0]); } int ans = 0; for (int i = 0; i < m - 1; ++i) { int[] a = r.get(i), b = r.get(i + 1); int t = (a[1] + b[1] + b[0] - a[0]) / 2; ans = Math.max(ans, t); } return ans; } }
-
// OJ: https://leetcode.com/problems/maximum-building-height/ // Time: O(RlogR) // Space: O(R) class Solution { public: int maxBuilding(int n, vector<vector<int>>& A) { map<long, long> m{ {1,0} }; for (auto &v : A) m[v[0]] = v[1]; long ans = 0; for (auto it = next(begin(m)); it != end(m);) { auto [x1, h1] = *prev(it); auto [x2, h2] = *it; if (h2 >= h1 + x2 - x1) { it = m.erase(it); } else { it = next(it); } } for (auto it = prev(end(m)); it != begin(m);) { auto [x1, h1] = *prev(it); auto [x2, h2] = *it; if (h1 >= h2 + x2 - x1) { m.erase(prev(it)); } else { it = prev(it); } } for (auto it = next(begin(m)); it != end(m); ++it) { auto [x1, h1] = *prev(it); auto [x2, h2] = *it; long x = (h2 - h1 + x1 + x2) / 2; ans = max(ans, h1 + x - x1); } auto [x, h] = *rbegin(m); ans = max(ans, h + n - x); return ans; } };
-
class Solution: def maxBuilding(self, n: int, restrictions: List[List[int]]) -> int: r = restrictions r.append([1, 0]) r.sort() if r[-1][0] != n: r.append([n, n - 1]) m = len(r) for i in range(1, m): r[i][1] = min(r[i][1], r[i - 1][1] + r[i][0] - r[i - 1][0]) for i in range(m - 2, 0, -1): r[i][1] = min(r[i][1], r[i + 1][1] + r[i + 1][0] - r[i][0]) ans = 0 for i in range(m - 1): t = (r[i][1] + r[i + 1][1] + r[i + 1][0] - r[i][0]) // 2 ans = max(ans, t) return ans
-
func maxBuilding(n int, restrictions [][]int) (ans int) { r := restrictions r = append(r, []int{1, 0}) sort.Slice(r, func(i, j int) bool { return r[i][0] < r[j][0] }) if r[len(r)-1][0] != n { r = append(r, []int{n, n - 1}) } m := len(r) for i := 1; i < m; i++ { r[i][1] = min(r[i][1], r[i-1][1]+r[i][0]-r[i-1][0]) } for i := m - 2; i > 0; i-- { r[i][1] = min(r[i][1], r[i+1][1]+r[i+1][0]-r[i][0]) } for i := 0; i < m-1; i++ { t := (r[i][1] + r[i+1][1] + r[i+1][0] - r[i][0]) / 2 ans = max(ans, t) } return ans } func max(a, b int) int { if a > b { return a } return b } func min(a, b int) int { if a < b { return a } return b }