LeetCode热题 42.接雨水

题目

思路:

通过画图观察我们其实可以很容易发现,每个柱子接多少水由这个地方左边最高的柱子和右边最高的柱子确定,因为总要形成一个坑嘛,然后就能接着确定:

当前柱子接水量 = min(左边最高柱子的高度, 右边最高柱子的高度) − 当前柱子高度
那么代码就很简单了:

复制代码
        int len = height.size();
        if (len < 3) return 0;  //  简单优化一下,如果小于3个柱子就形成不了坑,接不了水
			
        vector<int> left(len), right(len);  //  用两个数组保存每个位置的左右两边最高柱子的高度

        left[0] = height[0];  //  第一个柱子的左边最高是自己
        for (int i = 1; i < len; i ++ ){
            left[i] = max(height[i], left[i - 1]);  //  比较 左边最高柱子的高度和自己
        }

        right[len - 1] = height[len - 1];  //  最右边的柱子 右边最高的柱子高度是自己
        for (int i = len - 2; i >= 0; i --){
            right[i] = max(height[i], right[i + 1]);
        }

        int ans = 0;  
        
        //  累加接水量
        for (int i = 0; i < len; i ++ ){
            ans += min(left[i], right[i]) - height[i];
        }

        return ans;

单调栈写法:

上面是从每一列计算每根柱子的接水量,当然也可以从行计算。

这里有个算法 单调栈

我们确保这个栈是递减的,遍历每个柱子i,如果这个柱子比栈顶矮,那就让这个柱子进栈,这里对于i来说已经有了左边的墙,右边的墙还没来,我们继续遍历。 当遍历到柱子 i 高度大于栈顶柱子的高度,那柱子 i 就是右墙了,此时栈顶柱子就是那个接水坑的坑底。

怎么计算接水量呢?

我们先把坑底弹出栈,然后计算 宽 w = 此时柱子 i 的下标 - 栈顶柱子的下标 - 1

再计算 高 d = min(栈顶高度,柱子 i 的高度) - 坑底的高度

最后 宽 * 高 就是接水量了

当然不要忘记把 柱子 i 进栈,因为他可能是后面柱子的左墙。

下面是代码:

复制代码
stack<int> s;               // 单调递减 栈
int ans = 0;                // 接水量
int n = height.size();    

for (int i = 0; i < n; ++i) {                       // 顺序扫描
    while (!s.empty() && height[i] > height[s.top()]) {  // 当前柱子比栈顶高  那么 栈顶就是坑底
        int temp = s.top();   //  坑底柱子的下标
        s.pop();              // 先把坑底弹出去,后面才能看到左边界

        if (s.empty()) break; // 栈空了说明左边没墙,跳过

        int l = s.top();      // 新栈顶是左墙下标
        int w = i - l - 1;    // 水层宽度计算
        int d = min(height[i], height[l]) - height[temp]; // 水层深度计算
        ans += w * d;         // 一次性把这一整层水全部累加
    }
    s.push(i);                // 把当前柱子下标压进栈
}

return ans;                  
相关推荐
光羽隹衡15 小时前
机械学习逻辑回归——银行贷款案例
算法·机器学习·逻辑回归
能源系统预测和优化研究15 小时前
创新点解读:基于非线性二次分解的Ridge-RF-XGBoost时间序列预测(附代码实现)
人工智能·深度学习·算法
执笔论英雄15 小时前
【RL】ROLL下载模型流程
人工智能·算法·机器学习
yaoh.wang15 小时前
力扣(LeetCode) 100: 相同的树 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
SadSunset15 小时前
力扣题目142. 环形链表 II的解法分享,附图解
算法·leetcode·链表
Sunsets_Red16 小时前
2025 FZYZ夏令营游记
java·c语言·c++·python·算法·c#
iAkuya16 小时前
(leetcode)力扣100 19螺旋矩阵(方向数组/边界把控)
算法·leetcode·矩阵
爱编程的小吴16 小时前
【力扣练习题】热题100道【哈希】 最长连续序列
算法·leetcode·职场和发展
qq_3363139316 小时前
java基础-方法引用
java·开发语言·算法
Felven16 小时前
B. Lasers
算法