主题四:攒青豆

94 阅读2分钟

主题四:攒青豆

题目

现有 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的时候,则说明此处必然有豆子。

此处我们使用题目的例子进行讲解。

图片.png

首先我们定义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;
}