青训营主题创作(攒青豆)

51 阅读1分钟

当青训营遇上码上掘金


主题4 攒青豆

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

image-20230115113011540

解析

这道题的原理应该是短板效应,只不过由木桶变为了平面的几个柱子,选出柱子的次大值,即为高度,再乘以次大值柱子和最大值柱子之间的距离并减去中间的n个小柱子,就能得到这几个柱子所能接到的最大青豆数。

其实本质上就是双指针,一个left,一个right,再分别保存左指针和右指针遍历过的最大值,将其进行比较,如果maxleft小于maxright,则左边的青豆数为maxleft - height[left],同时left向右前进一个单位,否则右边的青豆数为maxright-height[right],同时right向左前进一个单位。

代码

复杂度分析

int trap(vector<int>& height) {
    int ans = 0;
    int maxleft = 0;
    int maxright = 0;
    int left = 0;
    int right = height.size() - 1;
    while (left <= right)
    {
        maxleft = max(maxleft, height[left]);
        maxright = max(maxright, height[right]);

        if (maxleft < maxright)
        {
            ans += maxleft - height[left];
            left++;
        }
        else
        {
            ans += maxright - height[right];
            right--;
        }
    }

    return ans;
}

时间复杂度:O(n),n为数组的长度,指针每移动一次的时间是o(1),最大长度不超过数组的大小

空间复杂度:O(1),只使用了常数级的变量

测试用例

输入:height = [5,0,2,1,4,0,1,0,3]

输出:17