当青训营遇上码上掘金
前言
虽然正在学习前端,但也深深了解到前端也需要掌握算法等知识。而算法类学习并不是死记硬背,而是要学习其思维,理解其步骤,并加以不断的练习.青训营快结束了,希望在此以此作为小练习,纪念一下这次艰苦的攒豆之旅。
任务描述-攒豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
任务分析
先简单分析一下,就是需要每次定下一根柱子为起始后,往后寻找仅次于自身高度的柱子or找到高于自身的柱子,然后利用长乘宽减去之间柱子的高度(好像有点抽象,但按图的意思是柱子的宽度不可忽略,单位为1)
进一步分析:
仔细想想,上一步分析有很多漏洞,或者说虽然很具象化但用代码实现起来很难。所以按代码的逻辑分析为:每次都要寻找当前列左右最高的柱子,形成一个“桶”。那么就可以遍历数组,将第i列左右最高墙找出,存起。然后再按列求出每一列存的豆子,只要当前列柱子高度小于左右最高柱,则当前列豆子数为左右最高柱之中,较低的高度减去当前高度。
关键点:
- 只有左右最高柱均大于当前列的height时,当前列才会有豆子
- 首列和末列不用考虑
任务实现
public static int col(int[] height) {
int len=height.length;
int sum=0;
int []left = new int[len];
int []right = new int[len];
for(int i=1;i<len-1;i++)
{
left[i] = Math.max(left[i-1], height[i-1]);
}
for(int i=len-2;i>0;i--)
{
right[i] = Math.max(right[i+1], height[i+1]);
}
for(int i=1;i<len-1;i++)
{
if(right[i]<left[i])
{
if(right[i]>height[i])
sum+=right[i] - height[i];
}
else
{
if(left[i]>height[i])
sum+=left[i] - height[i];
}
}
return sum;
}
结语
无论是什么任务,都要去逐步剖析,逐步解决问题,纸上谈兵对于编程而言是万万不可的。有错有bug很正常,慢慢去修改就是了。在本次编程过程中,第一个第二个版本的写法都会报错,都是一些基础问题,还有一次结果错了,是忘了加上“当前列低于左右最高列”的判断,所以每一个细节都要注意。