当青训营遇上码上掘金
主题4 攒青豆
现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。
解析
这道题的原理应该是短板效应,只不过由木桶变为了平面的几个柱子,选出柱子的次大值,即为高度,再乘以次大值柱子和最大值柱子之间的距离并减去中间的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