作者: Turbo时间限制: 1S章节: DS:栈
问题描述
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。
示例:
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
输入说明
输入若干个非负整数,以空格分隔。
输出说明
输出一个整数,表示结果。
输入范例
0 1 0 2 1 0 1 3 2 1 2 1
输出范例
6
框架
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
class Solution {
public:
int trap(vector<int>& height)
{
//填充本函数完成功能
}
};
int main()
{
int h;
vector<int> v;
while(cin>>h)
{
v.push_back(h);
}
int res=Solution().trap(v);
cout<<res<<endl;
return 0;
}
思路
根据题目描述,要求出每个位置的存水量:即分别找出该点左右两端最高的柱子,然后找出这两个最高点中较小的一个,与当前柱子的高度求差值,即为该点的最大存水量。
暴力
class Solution
{
public:
int trap(vector<int>& height)
{
//填充本函数完成功能
int res=0;
int len=height.size();
if(len<=2)
return res;
for(int i=0;i<len;i++)
{
int max_right=0,max_left=0;
for(int j=i;j<len;j++)
{
max_right=max(max_right,height[j]);
}
for(int j=i;j>=0;j--)
{
max_left=max(max_left,height[j]);
}
res+=min(max_left,max_right)-height[i];
}
return res ;
}
};
此时时间复杂度是O(n2),空间复杂度是O(1);
动态规划
class Solution
{
public:
int trap(vector<int>& height)
{
int size=height.size();
if(size<=2)
return 0;
vector<int> max_left(size);
vector<int> max_right(size);
max_left[0]=height[0];
for(int i=1;i<size;i++)
{
max_left[i]=max(height[i],max_left[i-1]);
}
max_right[size-1]=height[size-1];
for(int i=size-2;i>=0;i--)
{
max_right[i]=max(height[i],max_right[i+1]);
}
int res=0;
for(int i=0;i<size;i++)
{
res+=min(max_left[i],max_right[i])-height[i];
}
return res;
}
};
时间复杂度O(n)空间复杂度O(n);
栈
class Solution
{
public:
int trap(vector<int>& height)
{
int res=0,cur=0;
stack<int> st;
int len=height.size();
while(cur<len)
{
while(!st.empty() && height[cur]>height[st.top()])
{
int top=st.top();
st.pop();
//如果出栈后,栈即为空了,说明此时没有左边界,无法实现存水
if(st.empty())
break;
//判断能存水的宽度,即两个边界柱子之间的距离
int distance=cur-st.top()-1;
int bandry=min(height[cur],height[st.top()])-height[top];
res+=distance*bandry;
}
st.push(cur++);
}
return res;
}
};
用栈的思路解题时,栈用来存储柱子的索引, 将栈设计成一个单调递减的序列,每当遇到比之前柱子更高的柱子时,就有可能与前面的柱子结合,可以存水{条件就是当前栈不能为空,而且当前柱子的高度大于栈顶节点对应的柱子高度},此时可以进行是否存水判断,