LeetCode-42 接雨水(动态规划解法)

原题

接雨水

Problem Description

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
题图

Sample1

输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

Sample2

输入:height = [4,2,0,3,2,5]
输出:9

Tip

n == height.length
0 <= n <= 3 * 104
0 <= height[i] <= 105

思路分析:

①确定状态:设dp[i]表示height数组下标0~i的元素最多接多少雨水。
②边界条件:由于至少要3个柱子才能接到雨水,因此dp[0] = 0,dp[1] = 0。
③状态转移:这一步是最关键的。当前下标为i,要从i开始往左找,找到一个能装到最多水的柱子j。
有两种情况:
第一是左边的柱子全部低于当前柱子,此时要找左边柱子中最高的柱子;
第二是左边有高于当前柱子的柱子,则要从当前柱子向左找到第一根高于当前柱子的柱子。
情况1

情况1

情况2

情况2

可以写一个函数寻找柱子j。

int find(vector<int>& height, int index){
    
    
	//从右往左找到第一个大于该元素的 
	int i, max = -1, maxIndex = -1;
	for (i = index-1; i >= 0; i--){
    
    
		if (height[i] > height[index]){
    
    
			return i;
		}
		if (height[i] > max){
    
    
			max = height[i];
			maxIndex = i;
		}
	}
	//如果没有大于该元素的,则找剩下的元素中最大的 
	return maxIndex;
}

已知i与j,很容易算出i和j柱子围城的区域能装的雨水量,

令V1为当i柱子与j柱子间没有柱子时,两柱子所围成的区域能装的雨水量,则
V1 = min(height[i], height[j])*(i-j-1)
令V2 = sum(height[k]), j < k < i
则i柱子与j柱子间一共能装V = V1-V2

求出了i柱子与j柱子间能装的雨水量,再加上0~j号柱子能装的雨水量,就是0~j号柱子间能装的雨水量,即dp[i] = dp[j] + V;

AC代码

class Solution {
    
    
public:
	int find(vector<int>& height, int index){
    
    
		//从右往左找到第一个大于该元素的 
		int i, max = -1, maxIndex = -1;
		for (i = index-1; i >= 0; i--){
    
    
			if (height[i] > height[index]){
    
    
				return i;
			}
			if (height[i] > max){
    
    
				max = height[i];
				maxIndex = i;
			}
		}
		//如果没有大于该元素的,则找剩下的元素中最大的 
		return maxIndex;
	}
    int trap(vector<int>& height) {
    
    
		//dp[i]表示下标0~i的元素最多接多少雨水 
		int *dp = new int[height.size()+5];
		dp[0] = 0;
		dp[1] = 0; 
		for (int i = 2; i < height.size(); i++){
    
    
			int left = find(height, i);
			int h = (height[left]<height[i]?height[left]:height[i]);
			int v = (i-left-1)*h;
			for (int j = left+1; j < i; j++){
    
    
				v -= height[j];
			}
			dp[i] = v + dp[left];
		}
		return (height.size()>0?dp[height.size()-1]:0);
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_40735291/article/details/115962044