码迷,mamicode.com
首页 > 其他好文 > 详细

[ Leetcode ] No.42 接雨水

时间:2020-04-04 14:18:03      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:元素   遍历数组   画图   +=   判断   empty   pre   需要   top   

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

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

解题思路:

  • 首先构建两个栈,h存高度,idx存下标。
  • 遍历数组,将height[i]h.top()做比较
    1. height[i] <= h.top(),则将对应的高度和下标都入栈。
    2. height[i] > h.top(),则表明可能可以求得面积。
      实际上,对于index = k的方块而言,可能接住的雨水等于 min(left, right) * width
      left 表示左边第一个比它高的柱子高度,right表示右边第一个比它高的柱子高度。
      width表示宽度。
    3. 之所以是可能可求得面积,是因为可求面积的重要条件是,左右两边都有柱子。
      而恰如题目给出的例子中,[1, 2]这样的情况下,index = 1的那个柱子是没办法接雨水的。
      因为没左边的柱子。这样的情况需要特殊判断。
  • 在求面积的时候,要一直退栈退到栈顶元素比height[i]大或者相等
class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> h, idx;
        int sum = 0, tag = 0;
        int len = height.size();
        for(int i = 0; i < len; i++) {
            // 遍历到比栈尾还小的元素时,推入栈中
            if(h.empty() || h.top() >= height[i]) {
                h.push(height[i]);
                tag = 0;
                idx.push(i);
                continue;
            }
            while(h.top() < height[i]) {
                int temp = h.top();
                h.pop(), idx.pop();
                if(!h.empty()) {
                    int left = h.top(), left_h = idx.top();
                    sum += (min(height[i], left) - temp) * (i - left_h - 1);
                } else {
                    h.push(height[i]);
                    idx.push(i);
                    tag = 1;
                }
            }
            // 栈顶只可能比当前height[i]更大或相等
            while(!h.empty() && tag == 0) {
                if(h.top() == height[i]) {
                     h.pop(), idx.pop();
                     if(h.empty()) {
                        h.push(height[i]);
                        idx.push(i);
                        break;
                     }
                } else {
                    h.push(height[i]);
                    idx.push(i);
                    break;
                }
            }
        }
        return sum;
    }
};


心得:
虽然今天心情烦躁,但是鉴于抓住了一点思路,就打算自己写写这题。
因为之前看了不少关于单调队列、滑动窗口类型的题,感觉它们有点异曲同工的味道,很想尝试。
接近三个小时都在接雨水,提交了4次,最后AC打败了94%,美滋滋。
写着写着就没啥思路了,画图倒是一把好手!
继续跪谢阎总带我算法入门,三四百没白交。

[ Leetcode ] No.42 接雨水

标签:元素   遍历数组   画图   +=   判断   empty   pre   需要   top   

原文地址:https://www.cnblogs.com/recoverableTi/p/12631619.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!