「青训营 X 码上掘金」主题 4——攒青豆

49 阅读2分钟

当青训营遇上码上掘金

题目

现有 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 个单位的青豆。

具体思路

题目要求求出可以接住的青豆数量,我们知道两根柱子能借助的最大青豆数量取决于柱子较短的那一根,比如一根高度为5和一根高度为4的柱子放在一起最多可以接住4个单位的青豆
那么此时思路已经明显,我们从左到右遍历数组,寻找每一个柱子右侧的最大高度柱子(记为h),若当前柱子高于h则可以装下h个单位青豆,若小于h则装下h-当前柱子高度的青豆
例子: height = [5,0,2,1,4,0,1,0,3]
index=0,该位置柱子高度为5,右侧柱子最大高度为4,装下3个单位青豆
index=1,该位置柱子高度为0,跳过
index=2,该位置柱子高度为2,右侧柱子最大高度为4,装下4 - 2 = 2个单位青豆
index=3,该位置柱子高度为1,右侧柱子最大高度为4,装下4 - 1 = 2个单位青豆
index=4,该位置柱子高度为2,右侧柱子最大高度为3,装下3个单位青豆
index=5,该位置柱子高度为0,跳过
index=6,该位置柱子高度为1,右侧柱子最大高度为3,装下3 - 1 = 2个单位青豆
index=7,该位置柱子高度为0,跳过 index=8,该位置柱子为最后一个,结束

具体代码

public class Main {
   public static void main(String []args) {
      int []num = new int[]{5,0,2,1,4,0,1,0,3};
      int sum = 0;
      for(int i = 0;i<num.length;i++){
        if(num[i] == 0){
          continue;
        }
        int maxForRigth = findMax(num,i == (num.length-1)? i:i+1);
        if(num[i]>=maxForRigth){
            sum+=maxForRigth;
        }else{
          sum = sum +(maxForRigth-num[i]);
        }
      }
      System.out.println(sum);
   }

	 /**
	 * 查找数组最大值,从索引index开始找到末尾
	 */
   public static int findMax(int []num,int index){
     int max = num[index];
     for(int i = index;i<num.length;i++){
        if(num[i]>max){
          max = num[i];
        }
     }
     return max;
   }
}

具体代码链接