方法一:动态规划
class Solution {
public:
int trap(vector<int>& height) {
//动态规划拆分子问题解决:因为底边宽度为1,所以存储的水由高度差(左右两边围成的最低高度-自身高度)决定
//只需要先计算出每个位置能存储的水,它由min(左边最大高度,右边最大高度)-自身高度
int n=height.size();
if(n==0)
{
return 0;
}
vector<int>leftmax(n);
leftmax[0]=height[0];
for(int i=1;i<n;i++)
{
leftmax[i]=max(leftmax[i-1],height[i]);
}
vector<int>rightmax(n);
rightmax[n-1]=height[n-1];
for(int i=n-2;i>=0;i--)
{
rightmax[i]=max(rightmax[i+1],height[i]);
}
int sum=0;
for(int i=0;i<n;i++)
{
sum+=min(leftmax[i],rightmax[i])-height[i];
}
return sum;
}
};
方法二:双指针(降低空间复杂度)
class Solution {
public:
int trap(vector<int>& height) {
//用left,right两个指针分别代替leftmax,rightmax
int sum=0;
int left=0,right=height.size()-1;
int leftmax=0,rightmax=0;
while(left<right)
{
leftmax=max(leftmax,height[left]);
rightmax=max(rightmax,height[right]);
if(height[left]<height[right])//寻找每个位置左右低的位置
{
sum+=leftmax-height[left];//高度差
left++;
}
else
{
sum+=rightmax-height[right];
right--;
}
}
return sum;
}
};