当青训营遇上码上掘金

37 阅读1分钟

题目名称: 攒青豆

现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

image.png

以下为上图例子的解析:

输入:height = [5,0,2,1,4,0,1,0,3]  
输出:17  
解析:上面是由数组 [5,0,2,1,4,0,1,0,3] 表示的柱子高度,在这种情况下,可以接 17 个单位的青豆。

解决思路:

n个柱子组成的能接住的青豆数目可以看成每个柱子上最多能放多少青豆数.

每个柱子上最多能放多少青豆数取决于左右两边最高柱子的最小值减去当前柱子高度所得.

当左右不存在比他高的数就认为当前柱子最多只能放0个青豆. 整体最多能放多少豆子就是所有柱子上豆子的总和.

我们需要两个数组来记录左右最大的元素.

ans=0nmin(l_hightesti,r_hightesti)heightians = \sum_{0}^{n}{min(l\_hightest_i,r\_hightest_i)-height_i}

时空复杂度都为O(n)O(n),以下是CPP的实现.

#include <bits/stdc++.h>

using namespace std;

int main() {
    int n;
    cin>>n;
    vector<int>list(n);
    for(auto &i:list)cin>>i;
    vector<int>l(n,INT_MIN),r(n,INT_MIN);
    for(int i=0;i<n;++i){
        l[i] = list[i];
        if(i==0)continue;
        l[i] = max(l[i],l[i-1]);
    }
    for(int i=n-1;i>=0;--i){
        r[i] = list[i];
        if(i==n-1)continue;
        r[i] = max(r[i],r[i+1]);
    }
    int ans = 0;
    for(auto i=0;i<n;++i)ans +=min(l[i],r[i])-list[i];
    cout<<ans;
}