攒青豆
当青训营遇上码上掘金 刚开始看到这道题的时候有一点没有头绪,最开始的想法是有没有可能一层一层算,计算两个柱子中间有多少空,因为是一层一层算的,所有有空就加一,但是这样的话时间复杂度会比较大,因为每层都要遍历整个数组一遍,所以这种想法就放弃了,然后继续思考,查资料,想起来之前做过一道类似的题,是下雨求攒的雨水,和这题类似,所以查了下,是一道经典题,有一些解析,因为最高的和最低的之间最多的青豆只能是最低的,并且每一个最低的旁边的青豆都是能和他一平的,所以选出最高的,然后以最高的为分界线,从左向最高的遍历,再从右向最高的遍历,假设当前高度是h,数组元素下移高度为x,如果x比h高那么他俩之间不会有青豆,当前高度就更新为x的,如果x比h低,那所攒的青豆就是h-x,因为继续遍历肯定会有一个最高点,那么当前高度h和最高点之间一定会有x高的青豆,,至少这一条是肯定会有的,然后高度还是h,继续遍历数组,从左向最高点遍历一次,再从右向最高点遍历一次,就能求出最终结果。
step就是当前高度,首先遍历数组找出最高点,然后记录最高点元素下标,以他为中心,把数组分开,首先从左(第一个元素)向最高点遍历,如果当前数组元素高度x(为了简写,x指的是height[i])高于此时高度step,那么x和step之间不可能有青豆(自行理解),所以step更新成当前高度x,然后继续向下遍历数组,如果数组元素高度x小于step,那么他们之间就有step-x这么多青豆,那就记录到总数里,直到遍历到最高点
然后从右(最后一个元素)向最高点遍历,同理
代码如下:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin>>n;
int height[n];
for(int i=0;i<n;i++){
cin>>height[i];
}
if(n==0) {
return 0;
}
int step = 0;
int rains = 0;
int maxHeightI = 0;
int maxHeight = height[0];
for(int i=1;i<=n-1;i++) {
if(height[i] > maxHeight) {
maxHeight = height[i];
maxHeightI = i;
}
}
for(int i=0;i<=maxHeightI;i++) {
if(height[i] > step) {
step = height[i];
} else if(height[i] < step){
rains += step - height[i];
}
}
step = 0;
for(int i=n-1;i>maxHeightI;i--) {
if(height[i] > step) {
step = height[i];
} else if(height[i] < step){
rains += step - height[i];
}
}
cout<<rains<<endl;
return 0;
}