Leetcode---面试题17.21 直方图的水量

今天的每日一题,因为给的用例只有一个,再加上自己考虑问题不够全面,提交了四次才成功。。。没提交一次发现一点设计缺陷,然后改了再错,。。。自己还是太菜了
在这里插入图片描述

解题思路

直方图的蓄水能力取决于当前的最低点的高度以及当前最低点和最高点的距离。借鉴"双指针"和单调栈的思想,使用两个栈分别辅助进行顺序和倒序的计算,最后将两部分的结果相加就可以了。
对输入案例[0,1,0,2,1,0,1,3,2,1,2,1],以顺序为例。

  1. 栈为空,所以0入栈。“指针”指向1;
  2. 因为1比当前的栈顶元素0大,所以1入栈,“指针”指向0;
  3. 因为0比当前的栈顶元素1小,所以执行medium = medium + s.peek() - height[i],“指针”指向2;就像前面提到的,蓄水的量取决于当前栈顶元素,所以通过前面的公式可以消除内部“石块”对结果的影响;
  4. 因为2比当前的栈顶元素1大,所以2入栈,result += medium,medium重置为0,并记录当前栈顶元素的索引值index,“指针”指向1;
  5. 如此重复,直至对整个数组完成遍历,此时栈顶元素为3,index为7,result为5;

下面开始反向遍历,因为只需要找到最大的值后停止,所以j的索引值最小为上面的index
过程和顺序遍历的一样,最后得到结果1

两部分的结果加起来得到最终结果6

代码

class Solution {
    public int trap(int[] height) {
        int length = height.length;
        int medium = 0;
        int result = 0;
        Stack<Integer> s = new Stack();
        Stack<Integer> s1 = new Stack();

        int index=0;
        for(int i = 0; i<length;i++)
        {
            if(s.empty())
            {
                s.push(height[i]);
            }
            else
            {
                if(s.peek() <= height[i])
                {
                    s.push(height[i]);
                    index = i;
                    result += medium;
                    //System.out.println(result);
                    medium = 0;
                }
                else{
                    medium = medium + s.peek() - height[i];
                   // System.out.println(medium);
                }
            }
        }
        if (index == length-1)
            return result;

        //System.out.println("res"+result);
        medium = 0;
        for(int j = length-1; j>=index;j--)
        {
            if(s1.empty())
            {
                s1.push(height[j]);
            }
            else
            {
                if(s1.peek() <= height[j])
                {
                    s1.push(height[j]);
                    result += medium;
                    medium = 0;
                }
                else{
                    medium = medium + s1.peek() - height[j];
                }
            }
        }

        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值