hot 100 42. 接雨水

接雨水


问题描述

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。


样例输入

cpp 复制代码
height = [0,1,0,2,1,0,1,3,2,1,2,1]

样例输出

cpp 复制代码
6

评测用例规模与约定

n == height.length

1 <= n <= 2 * 104

0 <= height[i] <= 10^5


解析

可能是大家面对的第一道hard题,但在今天这个环境下也必须掌握了。解法也比较多,这里按官方解给出三种动规,单调栈,双指针。


参考程序

java 复制代码
class Solution {
    public int trap(int[] height) {
        int n = height.length;
        if (n == 0) {
            return 0;
        }

        int[] leftMax = new int[n];
        leftMax[0] = height[0];
        for (int i = 1; i < n; ++i) {
            leftMax[i] = Math.max(leftMax[i - 1], height[i]);
        }

        int[] rightMax = new int[n];
        rightMax[n - 1] = height[n - 1];
        for (int i = n - 2; i >= 0; --i) {
            rightMax[i] = Math.max(rightMax[i + 1], height[i]);
        }

        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans += Math.min(leftMax[i], rightMax[i]) - height[i];
        }
        return ans;
    }
}


class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0;
        stack<int> stk;
        int n = height.size();
        for (int i = 0; i < n; ++i) {
            while (!stk.empty() && height[i] > height[stk.top()]) {
                int top = stk.top();
                stk.pop();
                if (stk.empty()) {
                    break;
                }
                int left = stk.top();
                int currWidth = i - left - 1;
                int currHeight = min(height[left], height[i]) - height[top];
                ans += currWidth * currHeight;
            }
            stk.push(i);
        }
        return ans;
    }
};

class Solution {
    public int trap(int[] height) {
        int ans = 0;
        int left = 0, right = height.length - 1;
        int leftMax = 0, rightMax = 0;
        while (left < right) {
            leftMax = Math.max(leftMax, height[left]);
            rightMax = Math.max(rightMax, height[right]);
            if (height[left] < height[right]) {
                ans += leftMax - height[left];
                ++left;
            } else {
                ans += rightMax - height[right];
                --right;
            }
        }
        return ans;
    }
}

难度等级

⭐️(1~10星)

⭐️⭐️⭐️⭐️⭐️

以个人刷题整理为目的,如若侵权,请联系删除~

相关推荐
你这个代码我看不懂6 分钟前
引用计数法存在的问题
java·jvm·算法
yunyun3212315 分钟前
嵌入式C++驱动开发
开发语言·c++·算法
Storynone15 分钟前
【Day29】LeetCode:62. 不同路径,63. 不同路径 II,343. 整数拆分,96. 不同的二叉搜索树
python·算法·leetcode
小O的算法实验室16 分钟前
2025年SEVC SCI2区,基于强化学习辅助粒子群算法的污水处理厂进水流量估算及出水调度问题研究,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
ShineWinsu20 分钟前
sqlite api
数据结构
2301_7854035221 分钟前
代码随想录算法营总结
算法
yeflx22 分钟前
三维空间坐标转换早期笔记
人工智能·算法·机器学习
格林威42 分钟前
C++ 工业视觉实战:Bayer 图转 RGB 的 3 种核心算法(邻域平均、双线性、OpenCV 源码级优化)
开发语言·c++·人工智能·opencv·算法·计算机视觉·工业相机
Frostnova丶43 分钟前
LeetCode 3643.子矩阵垂直翻转算法解析
算法·leetcode·矩阵
2401_851272991 小时前
C++中的模板方法模式
开发语言·c++·算法