题解 [462.桥梁最高高度] | 豆包MarsCode AI 刷题

54 阅读2分钟

问题描述

牛妹需要用 n 根桥柱搭建一座桥,第一根桥柱和最后一根桥柱的高度已经确定,分别为 a 和 b。 为了保证桥梁的稳固性,相邻桥柱的高度差不能超过 1。牛妹想知道,在保证稳固性的前提下,桥梁中最高的桥柱能有多高。你需要帮助牛妹计算桥梁最高的桥柱的高度。

思路

根据题目的描述,我们希望尽可能的把桥柱往高建,也就是从一端尽可能把桥建高,之后到达某一个高度之后,我们能够在剩余桥柱数量内,回到另一端的高度,也就是所有桥柱的高度可以形成一个类似于二次函数的形状,我们要做的就是找到这个二次函数的最大值

这样问题就转变为,给定两端点值,如何找到最大值

首先可以枚举中点 mid。

我们可以想象从左端点加高到 mid,再从 mid 降低到右端点。

如果这个过程

  • 最后降低到右侧以下,说明 mid 太小,降低太多

  • 降低到右侧以上,说明 mid 太大,降低太少

在这个过程中,我们发现答案是由单调性的,也就是如果一个 mid 太小,那么更小的 mid 一定也不满足答案。

所以我们可以二分来找这个合适 mid

  • 小于等于右侧:mid 过小,l = mid + 1

  • 大于右侧:mid 过大,r = mid + 1

最后答案 l 是不满足要求的开始

所以最大高度就是 a + l - 1

由于如果到达不了右侧,需要返回 -1

所以返回时判断,如果当前找到的最大高度,小于两侧的最大值,那么返回 -1,否则返回找到的答案

解题方法

初始化左右端点,维护 mid 即左右端点的中间点

根据中间点计算最大高度 h

判断当前最大高度下降到右侧的高度与右侧当前高度

  • 小于等于右侧 l = mid + 1:说明中间点在 [mid + 1, r) 范围上

  • 大于右侧 r = mid - 1:说明中间点在 (l, mid - 1] 范围上

最后根据中间点计算最高高度

最后判断特殊情况,根据正确格式返回答案

复杂度

时间复杂度:

O(\log N)

对于给定的桥墩,二分查找最高的桥墩位置 O(\log N)

空间复杂度:

O(1)

仅使用个别变量 O(1)

代码

public class Main {
    public static int solution(int n, int a, int b) {
        int l = 0, r = n - 1;
        while (l <= r) {
            int mid = l + ((r - l) >> 1);
            int h = a + mid;
            if (h - n + 1 + mid <= b) l = mid + 1;
            else r = mid - 1;
        }
        int ans = l - 1 + a;
        return ans < Math.max(a, b) ? -1 : ans;
    }

    public static void main(String[] args) {
        System.out.println(solution(2, 1, 1) == 1);
        System.out.println(solution(3, 1, 1) == 2);
        System.out.println(solution(5, 3, 2) == 4);
        System.out.println(solution(5, 1, 100) == -1);
        System.out.println(solution(4, 1, 4) == 4);
    }
}