Leetcode 42 接雨水的问题
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
image.png
暴力破解
思路是找到每个块,左右两侧的最大值,那么该块可以存的水量就是
min(maxLeft, maxRight) - height[i]
后续思路也是如何去优化求左右max的方式
记录下leftMax和rightMax,O(n)的时间 空间复杂度
int trap(vector<int>& height)
{
if(height.empty())
return 0;
int size = height.size();
vector<int> leftMax(size), rightMax(size);
leftMax[0] = height[0];
for(int i=1; i<size; i++)
{
leftMax[i] = max(leftMax[i-1], height[i]);
}
rightMax[size-1] = height[size-1];
for(int i=size-2; i >= 0; i--)
{
rightMax[i] = max(rightMax[i+1], height[i]);
}
int ans=0;
for(int i=0; i<size; i++)
{
ans += min(leftMax[i], rightMax[i]) - height[i];
}
return ans;
}
双指针
int trap(vector<int>& height)
{
if(height.empty()) return 0;
int size = height.size();
int left =0, right=size-1, ans = 0;
int leftmax = height[0], rightmax = height[size-1];
while(left < right)
{
if (height[left] <= height[right])
{
if(leftmax >= height[left])
{
ans += leftmax - height[left];
}
else
{
leftmax = height[left];
}
left += 1;
}
else
{
if(rightmax >= height[right])
{
ans += rightmax - height[right];
}
else
{
rightmax = height[right];
}
right -= 1;
}
}
return ans;
}
借助数据结构栈的特性进行求解
我们可以不用像方法 2 那样存储最大高度,而是用栈来跟踪可能储水的最长的条形块。使用栈就可以在一次遍历内完成计算。
我们在遍历数组时维护一个栈。如果当前的条形块小于或等于栈顶的条形块,我们将条形块的索引入栈,意思是当前的条形块被栈中的前一个条形块界定。如果我们发现一个条形块长于栈顶,我们可以确定栈顶的条形块被当前条形块和栈的前一个条形块界定,因此我们可以弹出栈顶元素并且累加 。
网友评论