zoukankan      html  css  js  c++  java
  • <leetcode 42.接雨水>

    42. 接雨水

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

    示例 1:

    输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
    输出:6
    解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 
    

    示例 2:

    输入:height = [4,2,0,3,2,5]
    输出:9
    

    提示:

    • n == height.length
    • 0 <= n <= 3 * 104
    • 0 <= height[i] <= 105

     这道题目可谓经典,我做了三次还是没法流畅地写出来,所以我决定把各种解法给它整理一遍,这样我肯定会啦!

    方法一:水平方向 + 单调栈

    当前元素比栈顶元素大的时候,就弹栈,用当前栈顶与之前栈顶元素的高度差 乘以 当前i位置与当前栈顶元素的距离减一更新ans

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

    方法二:动态规划

      当前位置 i 能接住的最大雨水高度取决于它左右两边最高的柱子的高度中较低的那一个

    class Solution {
    public:
        int trap(vector<int>& height) {
            //动态规划
            int n = height.size();
            if(n == 0) return 0;
            vector<int> leftMax(n, 0);
            vector<int> rightMax(n, 0);
            leftMax[0] = height[0];
            rightMax[n - 1] = height[n - 1];
            for(int i = 1; i < n; i++){
                leftMax[i] = max(leftMax[i - 1], height[i]);
            }
            for(int i = n - 2; i >= 0; i--){
                rightMax[i] = max(rightMax[i + 1], height[i]);
            }
            int ans = 0;
            for(int i = 1; i < n - 1; i++){
                ans += min(leftMax[i], rightMax[i]) - height[i];
                //cout<<ans<<endl;
            }
            return ans;
        }
    };
  • 相关阅读:
    VC常用代码
    richedit
    vc++ 2005 发布程序
    管道应用之捕获控制台程序信息
    黑客基础知识编程(转)
    Get All IE Info from win32 api
    vc 界面编程常用方法(http://blog.emuch.net/244485/spacelistblogitemtypeid2708.html)
    使用ADO调用存储过程
    在C#中如何实现文件夹的复制(转)
    C语言开发病毒程序(转)
  • 原文地址:https://www.cnblogs.com/Dancing-Fairy/p/14607842.html
Copyright © 2011-2022 走看看