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. Thanks Marcos for contributing this image!
刚开始做错了,先找下降的,再找上升的,代码如下
class Solution { public: int trap(int A[], int n) { // Note: The Solution object is instantiated only once and is reused by each test case. if(NULL==A || n<=1) return 0; int beg=0,end=1,change=-1,max=0; int result = 0; while(beg<n) { while(end<n && A[end-1]>A[end]) //is down { ++end; } if(end<=n && end-beg>1)//is down { max = A[beg]; change = end-1; //up int tmp = 0; while(end<n && A[end-1]<=A[end] )//is up { ++end; } if(end-change==1)//not up { beg = end-1; continue; } if(end-1<n && max>A[end-1]) { max = A[end-1]; } //down for(int j=beg+1; j<end ; ++j) { if(A[j]<max) tmp += max-A[j]; } result += tmp; beg = end-1; continue; } beg = end; ++end; } return result; } };
Input: | [4,2,0,3,2,5] |
Output: | 5 |
Expected: | 9 |
分析:对某个值A[i]来说,能trapped的最多的water取决于在i之前最高的值leftMostHeight[i]和在i右边的最高的值rightMostHeight[i](均不包含自身)。
如果min(left,right) > A[i],那么在i这个位置上能trapped的water就是min(left,right) – A[i]。
有了这个想法就好办了,第一遍从左到右计算数组leftMostHeight,第二遍从右到左计算rightMostHeight。时间复杂度是O(n)。
int trap(int A[], int n) { // Note: The Solution object is instantiated only once. if(A==NULL || n<1)return 0; int maxheight = 0; vector<int> leftMostHeight(n); for(int i =0; i<n;i++) { leftMostHeight[i]=maxheight; maxheight = maxheight > A[i] ? maxheight : A[i]; } maxheight = 0; vector<int> rightMostHeight(n); for(int i =n-1;i>=0;i--) { rightMostHeight[i] = maxheight; maxheight = maxheight > A[i] ? maxheight : A[i]; } int water = 0; for(int i =0; i < n; i++) { int high = min(leftMostHeight[i],rightMostHeight[i])-A[i]; if(high>0) water += high; } return water; }