leetcode第238场周赛最高建筑高度

当时看见这道题感觉根本无从下手,数据量这么大,后来看了大佬的讲解视频后才知道这是线性DP。
感觉这道题对解题思路的拓展很有用,把题解敲了一遍,研究研究搬过来

任意一栋楼的最大高度受限于从左开始受限制的楼的高度以及从右开始受限制的楼的高度,因此预处理出来:

f[i]f[i]:从左开始到第ii条直线的截距最小值
g[i]g[i]:从右开始到第ii条直线的截距最小值

class Solution {
public:
    int maxBuilding(int n, vector<vector<int>>& h) {
        typedef long long LL;
        h.push_back({1 , 0});//第1栋楼的高度是0
        sort(h.begin() , h.end());
        if(h.back()[0] != n) h.push_back({n , n - 1});//显然最后一栋楼的不超过n-1,如果不存在第n栋楼的限制则加入。
        int m = h.size();
        vector<LL> f(m + 1 , INT_MAX) , g(m + 1 , INT_MAX);
        f[0] = -1;//第1栋楼的高度是0,因此第1条直线的截距是-1
        for(int i = 1 ; i < m ; i++)
        {
            LL x = h[i][0] , y = h[i][1];
            LL b = y - x;
            f[i] = min(f[i - 1] , b);
        }

        for(int i = m - 1 ; i >= 0 ; i--)
        {
            LL x = h[i][0] , y = h[i][1];
            LL b = x + y;
            g[i] = min(g[i + 1] , b);
        }

        LL res = 0;
        for(int i = 0 ; i < m ; i++)
        {
            LL x = h[i][0];
            res = max(res , min(x + f[i] , -x + g[i]));//到第i个有要求的建筑物时,所能取到的最高高度是min(x + f[i] , -x + g[i]);
            //与此同时,为与第i-1栋和第i栋有要求的建筑物之间的最大高度取决于正负两条对角线的交点
            if(i)
            {
                //求得交点(X,Y)
                LL Y = (f[i - 1] + g[i]) / 2;
                LL X = Y - f[i - 1];
                if(X >= h[i - 1][0] && X <= h[i][0])
                    res = max(res , Y);
            }
        }
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值