接雨水问题

108 阅读1分钟

image.png 思路:对柱子i,需要确定左边柱子最大值(mx_l)、右边柱子的最大值(mx_r);水得高度取决于两个最大值的最小值(mi),比较mi和arr[i],如果mi>arr[i],那个柱子i上的雨水就是mi-arr[i],否则就接不到雨水。

所以只需要创建数组arr_mx_l记录左边最大值、arr_mx_r记录右边最大值,然后就好算了; 这个方法的时间复杂度是O(n),空间复杂度也是O(n);

代码比较简单,相信你写起来还是比较简单的✌️😩😉

介绍下双指针法,l指向首部,r指向尾部,
重点:对比arr[l]、arr[r]二者大小,如果arr[l]<arr[r],舍弃arr[l]
让l++,这样确定了一个性质,那就是max(arr[l+1,l+2.......r])比arr[l]大,这时,只要记录左边最大值,这样对于arr[i]左右最大值都确定了,雨水就非常好求了,就是mx_l-arr[l],mx_l就是max(arr[0,1,2,...,l]);

当然arr[l]>=arr[r]也是同样的步骤,请看代码

class Solution {
public:
    /**
     * max water
     * @param arr int整型vector the array
     * @return long长整型
     */
    long long maxWater(vector<int>& arr) {
        // write code here
        int n=arr.size();
        if(n<3) return 0;
        int l=0,r=n-1;
        int mx_l=0,mx_r=0;//记录左边最大值、右边最大值
        long long sum=0;//返回的结果,记得是long long类型的
        while(l<r) {
            if(arr[l]<arr[r]) {
                //不要忘了更新mx_l、l
                if(arr[l]<mx_l) sum+=mx_l-arr[l];
                else mx_l=arr[l];
                ++l;
            } else {
                //不要忘了更新mx_r、r
                if(arr[r]<mx_r) sum+=mx_r-arr[r];
                else mx_r = arr[r];
                --r;
            }
        }
        return sum;
    }
};