【算法训练】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

二、思路

  1. 只想到了一种笨方法,逐一加入高度,当加入高度大于等于上一区域的max时,计算雨水,并更新max。
  2. 上面的方法没实现出来,其实想法是对的,但是卡在了左边界的设置上,其实不用纠结于“上一区域”,只需要将“洼地”的左侧节点作为边界,组成一个小型洼地计算出面积即可。

三、解题

public static class Solution {
    public int trap(int[] height) {
        int n = height.length; // 长度
        int area = 0;
        Deque<Integer> stack = new LinkedList<>(); // 双向队列模拟栈
        for (int i = 0 ; i < n ; i++){
            while (!stack.isEmpty() && height[i] > height[stack.peek()]){
                // 当栈不为空且当前高度大于栈顶高度时进入循环。  栈顶作为洼地
                int bottomLoc = stack.pop();
                if (stack.isEmpty()){
                    // 当栈空时,表明洼地没有左侧边界,无法构成完整洼地,直接break
                    break;
                }
                int leftLoc = stack.peek(); // 因为height[i]>height[bottom]时,才有可能构成洼地,因此栈内的元素一定是大于等于height[bottom]的
                int weight = i - leftLoc - 1; // 洼地长
                int high = Math.min(height[i],height[leftLoc]) - height[bottomLoc]; // 洼地高,左右边界的高度最小值减低洼处的高度
                area += weight * high; // 面积
            }
            stack.push(i);
        }
        return area;
    }
}
posted @ 2023-01-06 17:17  小拳头呀  阅读(19)  评论(0编辑  收藏  举报