解法1——动态规划
- 下标为i的柱子能攒到的青豆数量为攒完青豆后达到的最大高度值减去柱子高度height[i];
- 攒完青豆后达到的最大高度值为下标i柱子两边的柱子最大高度的最小值;
- 求得最大高度值后,一次遍历遍历求和便可得到结果
求解步骤
- 正向遍历,求解柱子i左侧柱子的最大值leftMax[i]:
leftMax[0] = height[0];
for(int i = 1; i < n; i++)
{
leftMax[i] = max(leftMax[i-1], height[i]);
}
- 反向遍历,求解柱子i右侧柱子的最大值rightMax[i]:
rightMax[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; i--)
{
rightMax[i] = max(rightMax[i + 1], height[i]);
}
- 最后一次正向遍历,求解结果
int res = 0;
for(int i = 0; i < n; i++)
{
res += min(leftMax[i], rightMax[i]) - height[i];
}
完整代码
int trap(vector<int>& height) {
auto n = height.size();
if(n == 0) return 0;
vector<int> leftMax(n);
vector<int> rightMax(n);
leftMax[0] = height[0];
for(int i = 1; i < n; i++)
{
leftMax[i] = max(leftMax[i-1], height[i]);
}
rightMax[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; i--) {
rightMax[i] = max(rightMax[i + 1], height[i]);
}
int res = 0;
for(int i = 0; i < n; i++)
{
res += min(leftMax[i], rightMax[i]) - height[i];
}
return res;
}
复杂度分析
- 第一次正向遍历时间复杂度O(n),反向遍历时间复杂度O(n),最后一次遍历时间复杂度O(n)。总的时间复杂度O(n)
- 空间复杂度O(n)