Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1]
, return 6
.
The above elevation map 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.
分析
算法一
遍历一遍,找到最高点,然后在左半边遍历,计算每个位置能够达到的最高值,如果当前高度<左边最高值,则容积为
maxleft - height[i]
否则更新maxleft
右边同理
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | class Solution { public : int trap(vector< int >& height) { if (height.empty()) return 0; int maxi = 0, maxh = height[0]; int volume = 0; for ( int i = 0; i < height.size(); ++i){ if (height[i] > height[maxi]) maxi = i; } int maxil = 0; for ( int i = 1; i < maxi; ++i){ if (height[i] < height[maxil]){ volume += height[maxil] - height[i]; } else { maxil = i; } } int maxir = height.size() - 1; for ( int j = height.size() - 1; j > maxi; j--){ if (height[j] < height[maxir]) volume += height[maxir] - height[j]; else maxir = j; } return volume; } }; |
算法二
Two Pointers,双指针法
左右双指针,每边各一个max值,maxleft 和 maxright,想象成水桶的长短边。左右双指针在内移时候随时更新maxleft 和 maxright。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Solution { public : int trap(vector< int >& A) { int left=0; int n = A.size(); int right=n-1; int res=0; int maxleft=0, maxright=0; while (left<=right){ if (A[left]<=A[right]){ if (A[left]>=maxleft) maxleft=A[left]; else res+=maxleft-A[left]; left++; } else { if (A[right]>=maxright) maxright= A[right]; else res+=maxright-A[right]; right--; } } return res; } }; |
算法过程如下:
初始化:
1 2 3 4 5 6 | L R 0 | | maxL 0 | | | maxR 0 | | | | | | res 0 | | | | | | | | 0 1 2 3 4 5 6 7 |
执行 1 次后,执行前:A[left:0] > A[right:7]
1 2 3 4 5 6 | L R 0 1 | | maxL 0 0 | | | maxR 0 3 | | | | | | res 0 0 | | | | | | | | 0 1 2 3 4 5 6 7 |
执行 2 次后,执行前:A[left:0] > A[right:6]
1 2 3 4 5 6 | L R 0 1 2 | | maxL 0 0 0 | | * | maxR 0 3 3 | | | | | | res 0 0 1 | | | | | | | | 0 1 2 3 4 5 6 7 |
执行 3 次后,执行前:A[left:0] > A[right:5]
1 2 3 4 5 6 | L R 0 1 2 3 | | maxL 0 0 0 0 | | * * | maxR 0 3 3 3 | | | | * | | res 0 0 1 3 | | | | | | | | 0 1 2 3 4 5 6 7 |
执行 4 次后,执行前:A[left:0] > A[right:4]
1 2 3 4 5 6 | L R 0 1 2 3 4 | | maxL 0 0 0 0 0 | | * * * | maxR 0 3 3 3 3 | | | | * | | res 0 0 1 3 4 | | | | | | | | 0 1 2 3 4 5 6 7 |
执行 5 次后,执行前:A[left:0] <= A[right:3]
1 2 3 4 5 6 | L R 0 1 2 3 4 5 | | maxL 0 0 0 0 0 4 | | * * * | maxR 0 3 3 3 3 3 | | | | * | | res 0 0 1 3 4 4 | | | | | | | | 0 1 2 3 4 5 6 7 |
执行 6 次后,执行前:A[left:1] <= A[right:3]
1 2 3 4 5 6 | L R 0 1 2 3 4 5 6 | * | maxL 0 0 0 0 0 4 4 | * | * * * | maxR 0 3 3 3 3 3 3 | | | | * | | res 0 0 1 3 4 4 6 | | | | | | | | 0 1 2 3 4 5 6 7 |
执行 7 次后,执行前:A[left:2] <= A[right:3]
1 2 3 4 5 6 | LR 0 1 2 3 4 5 6 7 | * * | maxL 0 0 0 0 0 4 4 4 | * * | * * * | maxR 0 3 3 3 3 3 3 3 | | * | | * | | res 0 0 1 3 4 4 6 9 | | | | | | | | 0 1 2 3 4 5 6 7 |
来源: