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

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

     

     上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

    示例:

    输入: [0,1,0,2,1,0,1,3,2,1,2,1]
    输出: 6

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/trapping-rain-water
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    看到这样的题目一般能快速想到的办法就是双指针了,last指针记录上一波的最高柱子,另一个从0开始递增,

    在遇到height[i] >= height[last_top]的时候,将i和last之间的高度差累计

    OK,可是这样会遇到个问题,在遇到最高的柱子右边的时候这规则就不适用了,是不是这样双指针就不行了呢。

    nonono,换个方向想想看,把整片柱子分开两段,最高柱子的左边和最高柱子的右边,

    这不就是两个双指针的思路么,最后就很容易计算最后的值了

    class Solution {
    public:
        int trap(vector<int>& height) {
           int last_top(0);
        int ret(0);
        int top_index(0);//
    
        for (int i=0;i < height.size(); i++)
        {
            if (height[i] > height[top_index]) {
                top_index = i;
            }
        }
        //1
        for (int i = 1; i <= top_index;)
        {
            if (height[i] >= height[last_top])
            {
                for (int j = last_top+1; j < i;++j)
                {
                    ret += height[last_top] - height[j];
                }
                last_top = i;
                i++;
            }
            else{
                i++;
            }
        }
        last_top = height.size() -1;
        for (int i = last_top - 1; i >= top_index;)
        {
            if (height[i] >= height[last_top])
            {
                for (int j = last_top - 1; j > i; --j)
                {
                    ret += height[last_top] - height[j];
                }
                last_top = i;
                i--;
            }
            else        {
                i--;
            }
        }
        return ret;     
        }
    };

    想复杂点的话,可以按照LeetCode官方解题,使用栈(好像这样比较高级,速度也比较快)

    用一个栈记录在遇到 height[current] > height[st.top() 之前的所有柱子的序号

    class Solution {
    public:
        int trap(vector<int>& height) {
               int ans = 0, current = 0;
        stack<int> st;
        while (current < height.size()) {
            while (!st.empty() && height[current] > height[st.top()]) {
                int top = st.top();
                st.pop();
                if (st.empty())
                    break;
                int distance = current - st.top() - 1;
                int bounded_height = min(height[current], height[st.top()]) - height[top];
                ans += distance * bounded_height;
            }
            st.push(current++);
        }
        return ans; 
        }
    };
  • 相关阅读:
    java学习(二)多态中成员变量详解
    java学习(一)静态代码块 构造代码块 构造方法的执行顺序及注意问题
    使sublimetext3在ubuntu下可以打中文和在windows的dos命令行下正常显示中文
    解决ubuntu更新中断后报错问题
    [译] 第一天:Bower
    [翻译] 30天学习30种技术
    T-SQL 练习整理
    Your folder can't be shared
    T-SQL PIVOT 基础使用
    SQL SERVER 基础语句学习(三)
  • 原文地址:https://www.cnblogs.com/gongkiro/p/12649992.html
Copyright © 2011-2022 走看看