返回介绍

solution / 1800-1899 / 1840.Maximum Building Height / README

发布于 2024-06-17 01:03:14 字数 6080 浏览 0 评论 0 收藏 0

1840. 最高建筑高度

English Version

题目描述

在一座城市里,你需要建 n 栋新的建筑。这些新的建筑会从 1 到 n 编号排成一列。

这座城市对这些新建筑有一些规定:

  • 每栋建筑的高度必须是一个非负整数。
  • 第一栋建筑的高度 必须 是 0 。
  • 任意两栋相邻建筑的高度差 不能超过  1 。

除此以外,某些建筑还有额外的最高高度限制。这些限制会以二维整数数组 restrictions 的形式给出,其中 restrictions[i] = [idi, maxHeighti] ,表示建筑 idi 的高度 不能超过 maxHeighti 。

题目保证每栋建筑在 restrictions 中 至多出现一次 ,同时建筑 1 不会 出现在 restrictions 中。

请你返回 最高 建筑能达到的 最高高度 。

 

示例 1:

输入:n = 5, restrictions = [[2,1],[4,1]]
输出:2
解释:上图中的绿色区域为每栋建筑被允许的最高高度。
我们可以使建筑高度分别为 [0,1,2,1,2] ,最高建筑的高度为 2 。

示例 2:

输入:n = 6, restrictions = []
输出:5
解释:上图中的绿色区域为每栋建筑被允许的最高高度。
我们可以使建筑高度分别为 [0,1,2,3,4,5] ,最高建筑的高度为 5 。

示例 3:

输入:n = 10, restrictions = [[5,3],[2,5],[7,4],[10,3]]
输出:5
解释:上图中的绿色区域为每栋建筑被允许的最高高度。
我们可以使建筑高度分别为 [0,1,2,3,3,4,4,5,4,3] ,最高建筑的高度为 5 。

 

提示:

  • 2 <= n <= 109
  • 0 <= restrictions.length <= min(n - 1, 105)
  • 2 <= idi <= n
  • idi 是 唯一的 。
  • 0 <= maxHeighti <= 109

解法

方法一:排序 + 数学

首先,我们将所有的限制条件按照建筑物的编号从小到大排序。

然后我们从左到右遍历所有的限制条件,对于每个限制条件,我们可以得到一个最高高度的上界,即 $r_i[1] = \min(r_i[1], r_{i-1}[1] + r_i[0] - r_{i-1}[0])$,其中 $r_i$ 表示第 $i$ 个限制条件,而 $r_i[0]$ 和 $r_i[1]$ 分别表示建筑物的编号以及建筑物的最高高度的上界。

然后我们从右到左遍历所有的限制条件,对于每个限制条件,我们可以得到一个最高高度的上界,即 $r_i[1] = \min(r_i[1], r_{i+1}[1] + r_{i+1}[0] - r_i[0])$。

这样,我们就得到了每个限制建筑物的最高高度的上界。

题目求的是最高建筑物的高度,我们可以枚举相邻两个限制条件之间的建筑物 $i$ 和 $i+1$,要使得高度最大,那么高度应该是先增大后减小,假设最大高度为 $t$,那么 $t - r_i[1] + t - r_{i+1}[1] \leq r_{i+1}[0] - r_i[0]$,即 $t \leq \frac{r_i[1] + r_{i+1}[1] + r_{i+1}[0] - r_{i}[0]}{2}$,我们取所有的 $t$ 中的最大值即可。

时间复杂度 $O(m \times \log m)$,空间复杂度 $O(m)$。其中 $m$ 为限制条件的数量。

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
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;
  }
}
class Solution {
public:
  int maxBuilding(int n, vector<vector<int>>& restrictions) {
    auto&& r = restrictions;
    r.push_back({1, 0});
    sort(r.begin(), r.end());
    if (r[r.size() - 1][0] != n) r.push_back({n, n - 1});
    int m = r.size();
    for (int i = 1; i < m; ++i) {
      r[i][1] = min(r[i][1], r[i - 1][1] + r[i][0] - r[i - 1][0]);
    }
    for (int i = m - 2; i > 0; --i) {
      r[i][1] = min(r[i][1], r[i + 1][1] + r[i + 1][0] - r[i][0]);
    }
    int ans = 0;
    for (int i = 0; i < m - 1; ++i) {
      int 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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文