advancing7

题目描述[原题链接][https://leetcode-cn.com/problems/trapping-rain-water/]

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

img

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

示例:

1
2
输入: [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6

算法描述

读完题不知道从何下手,看了题解,很多人都是用的dp的方法做的,对于我而言,dp的难度还是挺大的,所以采用了双指针的做法,指针如何移动,在什么时候移动这些是值得考虑的,初始化时,两指针分别指向开头和结尾,取到当前指针的值,分别比较,如果height[r]>height[l]时,需要更新左边最大值,看看l前面的那个值是否比当前左边的最大值大,即max(l_max,height[++l]),如果height[r]<=height[l]时,右边的最大值就需要更新了,即max(r_max,height[--r]);每次更新之后需要讲更新后的值与当前值的差与0比较,添加到答案中,ans+=(0,当前最大值-当前值),当左右指针相遇时,结束,返回答案;

C++代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
int trap(vector<int>& h) {
if(h.size()<=1)return 0;
int l=0,r=h.size()-1;
int l_max=h[l],r_max=h[r];
int ans = 0;
while(r>l){
if(h[r]>h[l]){
l_max = max(l_max,h[++l]);
ans+=max(0,l_max-h[l]);
}else{
r_max = max(r_max,h[--r]);
ans+=max(0,r_max-h[r]);
}
}
return ans;
}
};

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int trap(int[] height) {
if(height.length<=1)return 0;
int l = 0,r = height.length-1;
int l_max = height[l],r_max = height[r];
int ans = 0 ;
while(r>l){
if(height[r]>height[l]){
l_max = Math.max(l_max,height[++l]);
ans+=Math.max(0,l_max-height[l]);
}else{
r_max = Math.max(r_max,height[--r]);
ans+=Math.max(0,r_max-height[r]);
}
}
return ans;
}
}