【LeetCode】42. 接雨水

42. 接雨水

知识点:栈;单调

题目描述

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

示例

image

输入: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 个单位的雨水(蓝色部分表示雨水)。

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

解法一:单调

只有两边高中间低的时候才能去接雨水。所以可以维护一个单调递减的栈,这时候如果新来的元素小于等于栈顶,那就可以直接入栈,如果新来元素大于栈顶元素,因为栈顶下面的比栈顶大,新来的比栈顶大,这证明找到了能接雨水的地方。怎么求雨水呢,自然是宽*高,宽就是两堵墙之间的距离,也就是新来的和弹出后的新栈顶的索引距离,高度就是两堵墙之间较小的那个-弹出的高度,这就是能接水的容器的高度。

这又是用了单调栈的思想。单调栈真的很常用。

class Solution {
    public int trap(int[] height) {
        int water = 0;
        Stack<Integer> stack = new Stack<>();  //维持一个单调递减栈;栈里存放下标;
        int index = 0;
        while(index < height.length){
            while(!stack.isEmpty() && height[index] > height[stack.peek()]){
                int h = height[stack.pop()]; //出栈的高度,也就是底部的高度;
                if(stack.isEmpty()){
                    break;   //没有另一边墙没法接水;
                }
                int distance = index - stack.peek() - 1; //容器的宽度;
                int min = Math.min(height[stack.peek()], height[index]);  //两堵墙哪个低;
                water = water + distance*(min-h);
            }
            stack.push(index);
            index++;
        }
        return water;
    }
}
  • python
class Solution:
    def trap(self, height: List[int]) -> int:
        max_water = 0
        stack = []
        for i, cur_h in enumerate(height):
            while stack and cur_h > height[stack[-1]]:
                bottom_h = height[stack.pop()]
                if not stack:   # 左边没墙了
                    break
                min_h = min(height[stack[-1]], cur_h)
                max_water += (i-stack[-1]-1)*(min_h-bottom_h)
            stack.append(i)
        return max_water

相关链接

接雨水

相关题目

11. 盛最多水的容器
84. 柱状图中最大的矩形

posted @ 2021-08-13 09:35  Curryxin  阅读(58)  评论(0编辑  收藏  举报
Live2D