当青训营遇上码上掘金-攒青豆|青训营

59 阅读2分钟

当青训营遇上码上掘金

攒青豆详解

  • 主题 4:攒青豆

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

攒青豆.png

以下为上图例子的解析:

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

解题思路:

对每一列所包含的青豆都通过其左右最大高度得出,借助左右最高度的中的左最高度和右最高的最小值-当前列高度值即为该列所放青豆数量,通过遍历所有列数然后累计即可得到青豆的可盛放总量。左最大高度是通过比较取当前列说一列的左边最大高度和右边下一列的高度的最大值,右最大高度是通过比较取当前列上一列的右最大高度和左边方向下一列高度的最大值。

时间复杂度:O(n) 遍历n长度的数组

空间复杂度:O(n) 创建多个n长度数组

解题代码:

#include<iostream>
using namespace std;
int main() {
	int nums;
	vector<int> v;
	while (cin >> nums) {
	     v.push_back(nums);
             if (cin.get() == '\n')
			break;
		}
	Solution a;
	int n = a.trap(v);
        cout  << n;
}


class Solution {
public:
    int trap(vector<int>& height) {
        int n = height.size();
        if (n == 0) {
            return 0;
        }
        vector<int> leftMax(n);
        leftMax[0] = height[0];
        for (int i = 1; i < n; ++i) {
            leftMax[i] = max(leftMax[i - 1], height[i]);
        }

        vector<int> rightMax(n);
        rightMax[n - 1] = height[n - 1];
        for (int i = n - 2; i >= 0; --i) {
            rightMax[i] = max(rightMax[i + 1], height[i]);
        }

        int ans = 0;
        for (int i = 0; i < n; ++i) {
            ans += min(leftMax[i], rightMax[i]) - height[i];
        }
        return ans;
    }
};

作者:青训营官方账号
链接:juejin.cn/post/718775…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。