leetcode42 算法每天一题042:接雨水

暴力解法(由于时间限制无法通过)
water[i] = min(   
			max(height[0..i]),  max(height[i..end]) 
            ) - height[i]
#include <iostream>
#include<vector>
using namespace std;


class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size();
        int sum =0;
        if(height.empty())return sum;
        for(int i=0;i<n;i++){
            int l=0 ,r=0;//
            for(int j=0;j<=i;j++){
                l = max(l,height[j]);
            }
            for(int j=i+1;j<n;j++){
                r = max(r,height[j]);
            }
            if(min(l,r)- height[i] >0){
                sum = sum+min(l,r)- height[i];
            }
        }
        return sum;
    }
    
};


int main()
{
    cout<<"Hello World";
    Solution *mys = new Solution();
    vector<int> height={0,1,0,2,1,0,1,3,2,1,2,1};
    cout<<endl<< mys->trap(height);

    return 0;
}
备忘录法
class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size();
        int sum =0;
        if(height.empty())return sum;
        
        vector<int> l_max(n, 0);
        vector<int> r_max(n, 0);
        // 初始化 base case
        l_max[0] = height[0];
        r_max[n - 1] = height[n - 1];
        // 从左向右计算 l_max
        for (int i = 1; i < n; i++)
            l_max[i] = max(height[i], l_max[i - 1]);
        // 从右向左计算 r_max
        for (int i = n - 2; i >= 0; i--) 
            r_max[i] = max(height[i], r_max[i + 1]);

        for (int i = 1; i < n - 1; i++) 
            sum += min(l_max[i], r_max[i]) - height[i];

        return sum;
    }
    
};
单调栈解法

接雨水问题可以使用单调栈来解决,具体步骤如下:

  1. 定义一个单调栈,栈中存储的是数组中每个元素的索引。

  2. 从左到右遍历数组,对于每个元素,如果栈为空或者当前元素的高度小于等于栈顶元素的高度,则将当前元素的索引入栈。

  3. 如果当前元素的高度大于栈顶元素的高度,则弹出栈顶元素,计算当前元素与栈顶元素之间的水槽容量。容量的计算公式为:(当前元素的高度 - 弹出的栈顶元素的高度) * (当前元素的索引 - 栈顶元素的索引 - 1)。

  4. 将计算出的容量加入总容量中。

  5. 重复步骤2到步骤4,直到遍历完整个数组。

  6. 返回总容量。

这种解法的时间复杂度为O(n),空间复杂度为O(n),比暴力解法要更高效一些。

#include <iostream>
#include<vector>
#include<stack>
using namespace std;


class Solution {
public:
int trap(vector<int>& height)
{
    int ans = 0;
    stack<int> st;//  存储单调元素下标
    for (int i = 0; i < height.size(); i++)
    {
        while (!st.empty() && height[st.top()] < height[i])//新来的高度大于顶部的索引得到的高度
        {
            int temp = st.top();//取出
            st.pop();          //并删掉顶部的元素
            if (st.empty()) break;
            int l = st.top();
            int r = i;
            int h = min(height[r], height[l]) - height[temp];
            ans += (r - l - 1) * h;
        }
        st.push(i);
    }
    return ans;
}//作者:ikaruga 链接:https://leetcode.cn/problems/trapping-rain-water/solution/trapping-rain-water-by-ikaruga/

};


int main()
{
    cout<<"Hello World";
    Solution *mys = new Solution();
    vector<int> height={0,1,0,2,1,0,1,3,2,1,2,1};// 6
    cout<<endl<< mys->trap(height);

    return 0;
}

在这里插入图片描述

参考与更多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值