面试题 盛水 twitter

题目来源:http://news.cnblogs.com/n/192014/

 

用a[i]表示第i个墙的高度,墙的个数记为n

思考:

1)两个墙x,y之间可以盛水的条件是a[x],a[y]是a[x...y]中的前两大数;

2)如果a[1...x-1]中存在a[i]>a[x],那么用k来替代x并不会使a[x...y]中盛水减少,同样如果a[y+1...n]中存在a[j]>a[y],可以用j替代y不会使a[x...y]中的盛水减少;

3) 如果得到了a[1...n]中的前两大i,j,那么它们一定是整个区间盛水的最优边界,a[i...j]中的水位就是min{a[i],a[j]},只需要考虑两边:a[1...i]和a[j...n];对于左边,如果a[1...i-1]中最大值为a[k],那么进一步a[k...i]区间的盛水情况也确定了,只需要考虑a[1...k]了,右边也是如此。

4)设a[t]是a[1...n]中最大值,那么a[1...t]中的盛水情况可以通过维护左连续区间最大值确定,同样右区间a[t...n]也可以确定:首先找到最大值,然后分别从左右两边遍历。

5)一次遍历的做法很巧妙:维护两端区间的最大值,这样可以确定一端的水位了。

 

int cal(void)
{
    int ret = 0;
    int lmax = -1, rmax = -1;
    for (int i = 0, j = n-1; i <= j; ) {
        if (lmax < rmax) {
            if (a[i] > lmax) lmax = a[i];
            else ret += lmax-a[i];
            ++i;
        } else {
            if (a[j] > rmax) rmax = a[j];
            else ret += rmax-a[j];
            --j;
        }
     }
     return ret;
}

 

 

 

转载于:https://www.cnblogs.com/txd0u/p/3402841.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值