当青训营遇上码上掘金
题目
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入: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;
}
}