动态规划
思路参考
从左到右按每一列来看,只要左右两边的柱子高于自身柱子的高度即能接得住水,而装水的多少,根据木桶效应,我们只需要看左边最高的墙和右边最高的墙中较矮的一个就够了。
分两种情况:
1、较矮的墙的高度大于当前列的墙的高度
max_left[i] | max_right[i] | height[i] |
---|---|---|
2 | 1 | 3 |
所以此时能接得住1格子水
2、较矮的墙的高度小于等于当前列的墙的高度
max_left[i] | max_right[i] | height[i] |
---|---|---|
1 | 2 | 3 |
此时接不住水
所以整体思想就是遍历每一列,然后分别求出这一列两边最高的墙。找出较矮的一端,和当前列的高度比较,假如当前列的高度小于较矮的一端,则能接得住水,接到的数量是当前列和较矮一端的高度差
class Solution {
public:
int trap(vector<int>& height) {
int len=height.size();
// 注意要加上(len)不然报错
vector<int> max_left(len); // 记录左边最大值的数组
vector<int> max_right(len); // 记录右边最大值的数组
int sum=0;
for(int i=1;i<len-1;i++){
max_left[i]=max(max_left[i-1],height[i-1]);
// 动态规划,i的左边最大值=max(i-1的左边最大值,i本身的高度)
}
for(int i=len-2;i>=0;i--){
max_right[i]=max(max_right[i+1],height[i+1]);
// 动态规划,i的右边最大值=max(i+1的右边最大值,i本身的高度)
// 这里从后面开始遍历
}
for(int i=1;i<len-1;i++){
int n=min(max_left[i],max_right[i]);
// 能接得住雨水的前提是左右两边的柱子都比自己高
// 所以height[i]要小于左右柱子的较小值
if(n>height[i]){
sum+=(n-height[i]); // 满足则高度差为能接住的雨水
}
}
return sum;
}
};