Go语言基础 | 青训营笔记

50 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

  • 一、题目:攒青豆

    现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

image.png

image.png

二、我的解答

想法: 每次遍历的高度的数字可以向两边拓展,遇到比自己大的就接着拓展,小的就停止,然后用自己的高度乘以拓展的宽度,所以我们这里借助单调栈的方法。

我们使用一下单调递增栈。

思路:

1.设置一个单调递增的栈
2.当遇到小于栈顶元素的值,我们开始更新数据

具体做法:

首先,我们先遍历每个柱子的高度,前三个高度入栈,继续遍历,当遇到栈顶元素小于新加入的元素的情况,栈顶元素出栈。

那么,如果我们的栈里面还有存在着元素,我们所需求的单位青豆,即面积,就可以通过“底乘高”来计算。

底的计算:(当前遍历到的i)- (现在栈顶的高度元素)-1

高的计算:将新遍历的元素与当前栈的元素比较,取最小的值,得出h1。然后h1与第一步出栈的元素相减,得出高H。

于是,面积就可以通过(底* 高)的方式得出结果。

当栈顶元素大于新来的元素时,栈里面添加元素。

最终,按照题目要求,我们需要求出,按此排列的柱子能接住多少青豆,所以每次求出的面积的结果要累加起来,得到答案并输出我们的结果。

综上分析:代码如下:

class Solution {
   public int trap(int[] height) {
       int n = height.length ;
       Stack<Integer> s = new Stack<>();
       int res = 0 ;
       for(int i = 0 ; i < n ; i++){
           while(s.size() > 0 && height[s.peek()] <= height[i]){
              int t =  s.pop();
               if(s.size() > 0){
                   int h = Math.min(height[s.peek()],height[i]);
                   res += (i - s.peek() - 1 )* (h-height[t]) ;
               }
           }
           s.push(i);
       }
       return res ;
   }
}

三、个人总结

在分析问题的时候,我的思考时间较长,也阅读了有关单调栈的资料,解决问题的过程中,学到了很多新东西。