栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

力扣第42题【接雨水】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

力扣第42题【接雨水】

给定 n 个非负整数表示每个宽度为 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 个单位的雨水(蓝色部分表示雨水)。 

共三种解法

下面是三种解法的思想,以及代码(带有详细注释)

解法一 动态规划法

 找到每一列左边和右边(包括本身)的最高的一列,比较左右两边,取其较小值,这个值就是可以承接雨水的高度,注意在这里并不考虑本身有多高,因为我们在计算左右两边最高值的时候已经带着本身的高度,得出的最小值减去本身的高度就是这一列要填充的雨水

代码如下:

var trap = function(height) {
    let ans=0;
    let leftMax=[];//每一列左边的最大值
    let rightMax=[];//右边
    let lM=-Infinity;//左边最大值
    let rM=-Infinity;
    //第一步先确定左边的最大值
    for(let i=0;ilM)
        lM=height[i];
        leftMax[i]=lM;
    }
    //确定右边时要注意从最右边开始
    for(let i=height.length-1;i>=0;i--){
        if(height[i]>rM)rM=height[i];
        rightMax[i]=rM;
    }

    //第二步开始比较左右两边并确定每一列的雨水
    for(let i=0;i 

解法二 单调栈法

 使用一个栈来记录递减的下标,

 当下一个元素等于栈顶下标对应的元素时,将栈顶元素取出放入;

当前下标小于时,直接将当前下标入栈;

大于时,进行循环,将栈顶下标取出,如果此时栈内还有元素,则说明还有比该列更大的,所以就计算该列左边与右边的较小的值(同解法一的思路),但是由于是单调递减栈!故当前栈顶的元素下标就是左边最小值,与当前的进行比较,取较小值再减去该列的高度,就是要填补的高度h,宽度就是此时栈顶元素下标与i的差值减一得到w,h*w。循环直至栈顶元素不小于i位置或者栈为空

var trap = function(height) {
    let ans=0;
    let st=[0];
    for(let i=1;iheight[st[st.length-1]]){
                let temp=st[st.length-1];
                st.pop();
                if(st.length){
                    let w=i-st[st.length-1]-1;
                    let h=Math.min(height[i],height[st[st.length-1]])-height[temp]
                    ans+=w*h;
                }
            }
            st.push(i);
        }
    }
    return ans;
};

解法三 双指针法

属于方法一的简化版;

明确每一列的雨水数目是与其左边的最大值或者右边最大值相关的,且是由两值中的最小值决定的,那么我们就用双指针从数组两边遍历,当左边最大值小于右边最大值时,只需要关心左边这一部分即可,那么左指针就推进一步,反之同理。当然左右两边最大值是随时更新的。

var trap = function(height) {
    let ans=0;
    //左右最大值
    let lM=0;
    let rM=0;
    //左右指针
    let left=0;
    let right=height.length-1;
    while(left<=right){
        if(lMlM){
                lM=height[left]
            }else{
                ans+=lM-height[left];
            }
            left++;
        }
        else{
            if(height[right]>rM){
                rM=height[right];
            }else{
                ans+=rM-height[right];
            }
            right--;
        }
    }
    return ans;
};

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1031731.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号