[青训营 X 码上掘金] 主题4: 攒青豆

45 阅读1分钟

码上掘金主题4:攒青豆

当青训营遇上码上掘金

问题:攒青豆

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

a.png

以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]  
输出:17  
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。

思路分析

  1. 定义两个数,分别代表左右指针,分别对应左边和右边的数据,初始值分别为0和数组的长度减1

  2. 初始化两个值,分别对应左边和右边的最大值

  3. 通过左右最大值进行累加(通过列进行求),只要p_right_max[i]>p_left_max[i],青豆高度将由 p_left_max 决定;同理p_right_max[i]<p_left_max[i],青豆高度将由 p_right_max 决定

  4. 变量:p_left左指针,p_right右指针,

    p_left_max左指针的最大值,p_right_max右指针的最大值

    ans结果的值

  5. 判断条件:height[p_left] < height[p_right]

    height[p_left] >= p_left_max

    height[p_right] >= p_right_max

代码

class Solution {
    //双指针
    public int trap(int[] height) {
        //初始化变量
        int p_left=0, p_right = height.length-1;
        int p_left_max =0, p_right_max=0;
        int ans = 0;
         //循环左指针小于右指针
        while(p_left < p_right){
            boolean flag1=height[p_left] < height[p_right];
            //判断最大值在右边还是左边
            if(flag1){
                //判断此时的左边是否为最大值
                if(height[p_left] >= p_left_max){
                    p_left_max = height[p_left];
                }else{
                    ans += (p_left_max - height[p_left]);
                }
                p_left++;
            }else{
                // 判断此时的右边是否为最大值
                if(height[p_right] >= p_right_max){
                    p_right_max = height[p_right];
                }else{
                    ans += (p_right_max-height[p_right]);
                }
                p_right--;
            }
        }
        return ans;
    }
}

结果:

image.png