小白来报到,今天看见这样一道题:
这道题总的来说就是运用动态规划的思想从左到右遍历一便记录数值找最大值,再从右到左遍历一遍记录数值找最大值,最后将两者合并在一起看,找出较小的一方,再用这个较小一方的数值减去当前柱子高度就是当前柱子可以存储的雨水高度,要注意左边或者右边出现柱子高度为0的情况:
从左到右:left-max {0,1,1,2,2,2,2,3,3,3,3,3}
| | | | | | | | | | | |
从右到左:right-max {3,3,3,3,3,3,3,3,2,2,2,2}
在第一个数中,由于左边没有柱子,不可以存储雨水;第二个柱子经过比较查找后发现较小值为1,但是它的高度也为1,雨水为0;接着看第三个,此时左边最高的柱子小于右边,也就是1<3,因此当前最多存储为1 的雨水,而当前柱子高度为0,所以当前可存储的雨水为1-0=0,第四个和第二个相同,第五个.....以此类推,最后将所有的数据加在一起便能求出可以接多少的雨水了。
int trap(int* height, int heightSize){
int n = heightSize;
//判断当前柱子是否为0
if(n==0){
return 0;
}
遍历从左到右柱子的最高值
int leftmax[n];
memset(leftmax, 0, sizeof(leftmax));
leftmax[0] = height[0];
for (int i = 1; i < n; ++i) {
if(leftmax[i - 1]>height[i]){
leftmax[i] = leftmax[i - 1];
}
else{
leftmax[i] = height[i];
}
}
//遍历从右到左柱子的最高值
int rightmax[n];
memset(rightmax, 0, sizeof(rightmax));
rightmax[n - 1] = height[n - 1];
for (int i = n - 2; i >= 0; --i) {
if(rightmax[i + 1]> height[i]){
rightmax[i] = rightmax[i + 1];
}
else{
rightmax[i] = height[i];
}
}
//结合两次的数组数据比较,(当前可接雨水量=较小的一方-当前柱子高度)
int a = 0;
for (int i = 0; i < n; ++i) {
if(leftmax[i] > rightmax[i]){
a = a + rightmax[i] - height[i];
}
else{
a = a + leftmax[i] - height[i];
}
}
return a;
}