【leetcode】42. 接雨水(Java)

题目描述

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

题解

单调递减栈方法

  • 明确单调栈方法是按照行来统计雨水数量的。
  • 单调栈中存的数据是下标
  • 思路就是找到当前节点两侧第一个比它高的位置,计算行当前能装多少水,举例:

比如我们要求这一块雨水的体积。
在这里插入图片描述
遇到123的时候,由于都是递减的,直接入栈就好,此时状态应该是:
在这里插入图片描述
当遇到4了,比栈顶元素高,所以栈顶元素3出栈。此时状态应该如下:
在这里插入图片描述

其实此时已经找到了3左右两边第一个比它高的元素,左边比3高的元素为栈顶的2,右边比3高的元素为遍历遇到的4。那么此时第一块雨水的体积已经可以算出来了,就是:

//宽:右边坐标-左边的坐标 - 1 即:4 - 2 - 1。  高:两边较小的高度 - 当前的高度
//体积 = 宽 * 高
(i - deque.peekLast() - 1) * (Math.min(height[i], height[deque.peekLast()]) - height[tmp]);

计算完第一块体积后,发现4的高度和栈顶2的高度一样,此时4可以不入栈(入栈也没事儿,入栈后的情况,遇到5时,4弹栈,此时栈顶元素和4高度相同所以计算高的时候,高:两边较小的高度 - 当前的高度 = 0,所以计算出来的体积也是0,对结果没有影响。所以入不入栈都可以,为了代码简洁,就按照入栈讲解了)。

遍历到5的时候,4弹栈,计算出体积为0。然后5还比栈顶元素2高,所以2弹栈,此时状态为
在这里插入图片描述
此时就可以计算第2块雨水的体积,同样是宽 * 高
宽:右边坐标-左边的坐标 - 1 即:5 - 1 - 1。 高:两边较小的高度 - 当前的高度 即:min(2, 3) - 1
累加到res上。

完整代码:

class Solution {
    public int trap(int[] height) {
        Deque<Integer> deque = new LinkedList<>();
        int res = 0;
        for (int i = 0; i < height.length; i++){
        	//遇到比栈顶大的元素
            while (!deque.isEmpty() && height[i] > height[deque.peekLast()]){
                int tmp = deque.pollLast();
                if (!deque.isEmpty()){
                	//根据栈顶元素,弹栈出来的tmp,和遍历遇到的i,计算这一块的体积
                    res += (i - deque.peekLast() - 1) * (Math.min(height[i], height[deque.peekLast()]) - height[tmp]);
                }
            }
            deque.add(i);
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值