力扣面试题17.21——直方图的水量

给定一个直方图(也称柱状图),假设有人从上面源源不断地倒水,最后直方图能存多少水量?直方图的宽度为 1。

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的直方图,在这种情况下,可以接 6 个单位的水(蓝色部分表示水)。 感谢 Marcos 贡献此图。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

题解

这道题想对了思路就是一道比较简单的问题
一般而言,看到这道题肯定首先想的是找到所有凹的地方,然后求出这些加和
这么想是没有问题的,问题在于是否想到每次只是单独求每个位置,而不是一整块的凹的地方
我们可以首先创建两个数组pre[] suf[]分别表示到height[i]为止前面最高的数值和后缀最大的数值
这样我们遍历height[i]的时候,只需要考虑该位置i左边的最大值preMax和右边最大值sufMax就好
因为该位置i处必定贡献了min(preMax,sufMax) - height[i]的水量,当然前提是preMax, sufMax都大于height[i]

代码

点击查看代码
class Solution {
public:
    int trap(vector<int>& height) {
        const int N = 100000+10;
        int pre[N],suf[N];
        int n = height.size();
        if(n != 0){
            pre[0] = height[0];
            suf[n - 1] = height[n - 1];
        }
        for(int i = 1 ; i <n; i++){
            pre[i] = max(pre[i-1],height[i]);
            suf[n - i - 1] = max(suf[n - i], height[n - i - 1]);
        }
        int ans = 0;
        
        for(int i = 1; i < n - 1; i++){
            if(pre[i - 1] > height[i] && suf[i + 1] > height[i]){
                ans += (min(pre[i - 1], suf[i + 1]) - height[i]);
            }
        }
        return ans;

    }
};
posted @ 2022-09-26 20:17  白菜茄子  阅读(24)  评论(0编辑  收藏  举报