作为字节青训营第五届go后端成员,我选择了**「青训营 X 码上掘金」**,中的主体4,攒青豆!
主题4:攒青豆
题目意思:现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
`以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。`
对c/cpp语言还是比较熟悉的,所以就用c++来解<攒青豆>
代码如下:
#include<bits/stdc++.h>
using namespace std;
int max(int a,int b){
return a>b?a:b;
}
int min(int a,int b){
return a>b?b:a;
}
int main(){
int a[10086];
int len=0;
int x;
while(cin>>x){
a[len++] = x;
if(cin.get()=='\n') break;
}
if(len<=2){
cout<<0<<endl;
return 0;
}
int lmax=a[0],rmax=a[len-1];
int l=1,r=len-2;
int ans=0;
while(l<=r){
if(lmax < rmax){
ans += max(min(lmax,rmax)-a[l],0);
lmax = max(lmax,a[l]);
l++;
}
else{
ans += max(min(lmax,rmax)-a[r],0);
rmax = max(rmax,a[r]);
r--;
}
}
cout<<ans<<endl;
return 0;
}
运行截图:
码上掘金平台代码链接:
思路理解:
使用双指针的方法
首先定义一个数组a[10086],假设容量为10086,定义一个计算数组长度的变量为len,用while(cin>>x)的方式来不断往数组里按序排列的输入元素,当敲EnTer键时结束输入,在输入的过程中,每输入一个元素,len自增一次,结束后,len的大小即使数组的长度,定义4个变量,lmax=a[0],rmax=a[len-1]l=1,r=len-2;
思路:求整个排列上能接住多少柱子,也就是求每个柱子上能接到的青豆数的和,每根柱子上能接到的青豆数是该柱子左右两边最高柱子值中最大值中的较小值,然后再减去自身柱子的高度,值得注意的是,得出来得结果要与0做比较,否则算出来的结果,可能会造成某根柱子接到的青豆数为负数,这样的话,不切实际,要去与0比较后较大的哪一个,定义左右双指针,用ans记录结果,当l>r结束。