当青训营遇上码上掘金——攒青豆

61 阅读1分钟

当青训营遇上码上掘金——攒青豆java实现

主题4:攒青豆

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

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

解题思路

可以将数组中的元素看成一个柱子,两个柱子就可以组成一个装青豆的桶,一个桶能接住多少青豆,取决于桶两边柱子的高度。首先找出高度最高的柱子,以这个柱子为一个桶边,桶的容量就由另一条桶边决定。以最高边为中心,从左右两边开始遍历,依次计算每个桶装青豆的数量,求和得到能接住的总的青豆数。

代码实现

public int trap(int[] height) {
    int res=0;
    //找出最高点
    int high=0;
    int highIndex=0;
    for(int i=0;i<height.length;i++){
        if(height[i]>high){
            high=height[i];
            highIndex=i;
        }
    }

    //计算左边
    int l=0;
    for(int i=0;i<highIndex;i++){
        l=Math.max(l,height[i]);
        if(height[i]<l) res+=l-height[i];
    }

    //计算右边
    int r=0;
    for(int i=height.length-1;i>highIndex;i--){
        r=Math.max(r,height[i]);
        if(height[i]<r) res+=r-height[i];
    }
    return res;
}

复杂度分析

首先遍历数组找出值最大的元素,再从左右两边开始遍历计算能装的青豆数,时间复杂度为O(n)

需要变量存储值最大的元素及其的位置、分别存储左右两边的最大元素值及总青豆数,空间复杂度为O(1)