Leetcode - 42 接雨水(一维)

原题链接

分析

首先分析题目:

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

n == height.length

1 <= n <= 2 * 104

0 <= heighti <= 105

也就是计算所有接到的雨水的数量。先竖着看,每次计算一个位置可以保存的雨水,也可以横着看,每次计算一小横行可以存储多少雨水。

1 竖着看

竖着看,一个位置存储的雨水就取决于左右两侧柱子的较小值。

所以只需要计算每个位置左右两侧最大值,然后取出较小值计算就可以了。

那么就使用数组存储就可以,时间复杂度O(n) ,空间复杂度O(n)。

还可以进一步优化,优化空间复杂度到O(1),也就是不提前存储,而是直接每次计算。

使用双指针,同时使用两个数值,记录当前左右两侧最高值。

由于每个位置能够存储的水和两侧最高柱子的较小值有关。那么对于左指针,如果左侧最高值小于右侧,也就是右侧一定更高(右侧可能还有更高的柱子,左侧就是当前确定最大值),两侧中较小值一定是左侧的。那么就可以计算出这个位置可以存储的水量。右侧反之同理。

例如当前位置

l=1,r=11,lmax=1,rmax=2(这里表示高度)

那么就可以确定当前 l 位置存储的水量。

代码

cpp 复制代码
class Solution {
public:
    int trap(vector<int>& height) {
        int n=height.size();
        int l=0;
        int r=n-1;
        long long ans=0;
        int lm=0;
        int rm=0;
        while(l<r){
            lm=max(lm,height[l]);
            rm=max(rm,height[r]);
            if(lm<rm){
                ans+=lm-height[l++];
            }else{
                ans+=rm-height[r--];
            }
        }
        return ans;
    }
};

横着看

首先注意到,如果能够存储水,柱子的结构应该是凹形的。

使用单调栈,栈底到栈顶存储的柱子高度应该逐渐下降。每次如果遍历的柱子比栈顶高就说明当前形成了一个凹形区域,可以计算当前部分的存储水量,如下:

代码

cpp 复制代码
class Solution {
public:
    int trap(vector<int>& height) {
        int n=height.size();
        stack<int>s;
        long long ans=0;
        for(int i=0;i<n;i++){
            while(!s.empty()&&height[i]>height[s.top()]){
                int m=s.top();
                s.pop();
                if(s.empty()){
                    break;
                }
                int l=s.top();
                ans+=(i-l-1)*(min(height[i],height[l])-height[m]);
            }
            s.push(i);
        }
        return ans;
    }
};
相关推荐
牧羊人.33311 小时前
卷积神经网络之VGG
人工智能·深度学习·神经网络·算法·cnn
akinggw12 小时前
libsherpacore - 基于 sherpa-onnx 的 C++ 语音交互静态库
c++·交互·语音识别
xiaoye-duck12 小时前
《C++ 项目:手写大模型接入 SDK》ChatGPT接口设计(中):全量响应实现和测试
网络·c++·语言模型·chatgpt
小郎君65812 小时前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
JJJennie77712 小时前
MAI Gateway私有化部署全攻略:大模型网关如何接入?附架构图
算法·gateway·ai网关·魔芋ai
東隅已逝,桑榆非晚13 小时前
算法3.双指针法-快乐数
c++·笔记·学习·算法
专注仿真13 小时前
卷积神经网络(CNN)算法详解
人工智能·python·算法·代码·大模型训练
FII工业富联科技服务13 小时前
多智能体如何进入制造现场?从业务协同到数字孪生验证
大数据·人工智能·算法·机器人·制造·数字孪生
≮傷£≯√13 小时前
httpserver_QNetWorkClient
算法
Evand J13 小时前
【PMSM例程11】永磁同步电机(PMSM)基于UKF的转速与转子位置估计。附下载链接
算法·matlab·卡尔曼滤波·永磁同步电机·ukf·pmsm·位置估计