问题描述
解法一、动态规划
max_left[i]: 代表i位置左边最高的柱子的高度,处理完就如绿色阴影覆盖的区域。
max_right[i]: 代表i位置右边最高的柱子的高度,处理完如红色阴影覆盖的区域。
我们只讨论单个区域能装多少水。那么在 i 位置,我们能装多少水呢?
很容易理解,i 区域能装多少水取决于i 左右两边柱子的高度。我们找到 i 左边最高的高度max_left[i] 和右边最高的高度max_right[i] ,取两个中的最小值min(max_left[i] , max_right[i]),再减去自身的高度height[i], 就是在 i 位置我们可以装的水量。最后将每个位置的水量相加总和即可。
举个例子就明白了:
代码如下:
int trap(int* height, int heightSize){
if(heightSize == 0)
return 0;
int i,ans=0;
int max_left[heightSize],max_right[heightSize];
max_left[0] = height[0]; max_right[heightSize-1] = height[heightSize-1];
for(i=1; i<heightSize; i++)
max_left[i] = max(height[i],max_left[i-1]);
for(i=heightSize-2; i>=0; i--)
max_right[i] = max(height[i],max_right[i+1]);
for(i=0; i<heightSize; i++)
ans = ans + min(max_left[i],max_right[i])-height[i];
return ans;
}
解法二、双指针法
双指针法相对于第一种方法的好处就是其空间复杂度为o(1);
详细参考:
https://leetcode-cn.com/problems/trapping-rain-water/solution/tu-jie-jie-yu-shui-dong-tai-gui-hua-he-shuang-zhi-
int trap(int* height, int heightSize){
if(heightSize==0)return 0;
int left=0,right = heightSize-1;
int max_left = height[0],max_right = height[heightSize-1];
int ans=0;
while(left <= right){
max_left = max(max_left,height[left]);
max_right = max(max_right,height[right]);
if(max_left < max_right){
ans = ans + max_left - height[left];
left++;
}else{
ans = ans+max_right - height[right];
right--;
}
}
return ans;
}