主题四:攒青豆
题目
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
以下为上图例子的解析:
输入:height = [5,0,2,1,4,0,1,0,3]
输出:17
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。
解题思路
我的第一直觉是暴力解法,一行一行进行求解,也就是说,先求第一行的豆子有多少,然后求第二行的豆子有多少,以此类推,直到求出所有的豆子多少。
分情况讨论即可:
求第n层的豆子,如果遇到当前坐标的高度小于n,并且两边的高度大于等于n的时候,则说明此处必然有豆子。
此处我们使用题目的例子进行讲解。
首先我们定义res表示最后的豆子总量,ans为当前这个坑的豆子量,都初始化为0。
然后,从左到右寻找高度大于层数n的柱子,然后开始更新temp,往右走一格就temp + 1,直到遇到另一个高度大于层数n的柱子。此时就把temp加到最终豆子总量的ans中,并且temp清0,继续循环。
下面以第一层开始讲解:
height[0] = 5,大于层数n = 1,开始更新temp
height[1] = 0,小于层数n = 1,temp++
Height[2] = 2,大于层数n = 1,ans += temp,temp = 0
直到height[4] = 4,大于层数n = 1,temp开始更新
height[5] = 0,小于层数n = 1,temp++
height[6] = 1,等于层数n = 1,ans += temp,temp = 0
……以此类推
题解
// 获取最大高度
int getHeightest(vector<int> &height) {
int res = -1;
for (auto &num: height) {
if (num > res) {
res = num;
}
}
return res;
}
int main() {
vector<int> height;
int res = 0;
int heightest = getHeightest(height);
for (int i = 1; i <= heightest; i++) {
bool isTemp = false;
int temp = 0;
for (int j = 0; j < height.size(); j++) {
if (isTemp && height[j] < i) {
temp++;
}
if (height[j] >= i) {
res += temp;
temp = 0;
isTemp = true;
}
}
}
cout << res << endl;
return 0;
}