牛客网-容器盛水问题

在这里插入图片描述
a[left, right] 是一个水槽, 递归的看,可能中间存在某个mid, a[left, mid]也是水槽,a[mid, right]也是水槽,那么怎么解决这个递归问题呢?

本人的方法是用一把刀横着去切水槽:sum表示水槽容积

1.假设用一把 刀 横着去切这个水槽 a[left, right] 那么从哪边开始切呢?当然是从小的一边开始切

if a[left] <= a[right] 从左边向右切一刀水槽:

怎么切?没有遇到挡住的障碍,说明可以装水,一路切过去,同时计算sum += a[left] - a[l]

if a[left] > a[right] 从右边向左切一刀水槽:

怎么切?没有遇到挡住的障碍,说明可以装水,一路切过去,同时计算sum += a[right] - a[r]

2.切完一次,left 和 right 重新移到递归小水槽的两边, 于是又递归成了切水槽问题(计算水槽容积问题),返回 1 计算,直到 l = r

整个数组遍历一次,时间复杂度:O(n) 空间复杂度O(1)

class Solution {
public:
    /**
     * max water
     * @param arr int整型vector the array
     * @return long长整型
     */
    long long maxWater(vector<int>& arr) {
        int l =0, r = arr.size()-1;
        long long sum=0; //注意要long long 否则很可能加法溢出
        while(l<r){//左右不等,没砍完
            if(arr[l] <= arr[r]){ // 左边比右边小,从左边开始砍
                int left = arr[l]; //基准
                while(l+1<r && arr[l+1]< left){ //如果右边一个位置比基准矮,刀无阻碍
                    sum += (left-arr[l+1]); //刀下方可以装水
                    l++;
                }
                l++; //刀遇到到第一个碰瓷(碰刀)的柱子
            }
            else{ //否则从右边开始切
                int right = arr[r]; //以右边最低为基准
                while(r-1>l && arr[r-1] < right){//如果左边一个位置比基准矮,刀无阻碍
                    sum += (right -arr[r-1]); //刀下方装水
                    r--;
                }
                r--; //向左移移到第一个碰瓷(碰刀)的柱子
            }
        }
        return sum;
    }
};

转载牛客网用户 千帆L

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值