Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.
思路
本题使用了两种方法求解,第一种方法可自行研究,本文着重讲述动态规划法。
这道题想了挺久,始终局限于计算局部的接水量。其实将思路放开到全局就会容易很多,对于每一个点的接水量,其实取决于左右最高点,等于最高点的较小值减去该点高度的差(需要判断一下差值是否是正数哦)。
状态转移方程
left[i] = max(height[i], left[i-1])
right[i] = max(height[i], right[i+1])
边界条件
left[0] = height[0]
right[len-1] = height[len-1]
寻最值两端分别求解法
class Solution {
public:
int trap(vector<int>& height) {
int sum = 0;
int maxn = -1, maxi;
int len = height.size();
for(int i = 0; i < len; i++)
{
if(height[i] > maxn)
{
maxi = i;
maxn = height[i];
}
}
int temp = height[0];
for(int i = 1; i < maxi; i++)
{
if(height[i] > temp)
temp = height[i];
else
sum += temp - height[i];
}
temp = height[len-1];
for(int j = len-1; j > maxi; j--)
{
if(height[j] > temp)
temp = height[j];
else
sum += temp - height[j];
}
return sum;
}
};
动态规划法
class Solution {
public:
int trap(vector<int>& height) {
int sum = 0;
int len = height.size();
int left[20005], right[20005];
left[0] = height[0];
for(int i = 1; i < len; i++)
left[i] = max(height[i], left[i-1]);
right[len-1] = height[len-1];
for(int i = len-2; i >= 0; i--)
right[i] = max(height[i], right[i+1]);
int min_level;
for(int i = 1; i < len-1; i++)
{
min_level = min(left[i], right[i]);
if(min_level > height[i])
sum += min_level - height[i];
}
return sum;
}
};