Leetcode: 42. Trapping Rain Water
求下雨後,給定的地形上積水最大的容積。有點接近與面試會問的提醒。
Stack解法
首先,積水的地方肯定是兩邊高中間低的地方。所以目標是找到遞減序列後的遞增序列,那麼這兩個序列中間必定會積水。需要把遞減序列的高度和容積用stack存起來。
class Solution {
public:
int trap(int A[], int n) {
if(n<3) return 0;
stack<int> s;
s.push(0);
int water = 0;
for(int i=1; i<n; i++) {
if(A[i]>A[s.top()]) {
int bottom = A[s.top()];
s.pop();
while(!s.empty() && A[i]>=A[s.top()]) {
water += (A[s.top()]-bottom)*(i-s.top()-1);
bottom = A[s.top()];
s.pop();
}
if(!s.empty()) water += (A[i]-bottom)*(i-s.top()-1);
}
s.push(i);
}
return water;
}
};
two pointers解法
使用兩個指針,對於對任意位置i,在i上的積水,由左右兩邊最高的bar:A[left] = max{A[j], j<i}, A[right] = max{A[j], j>i}
決定。定義Hmin = min(A[left], A[right])
,則積水量Si爲:
Hmin <= A[i]
時,Si = 0
Hmin > A[i]
時,Si = Hmin - A[i]
class Solution {
public:
int trap(int A[], int n) {
if(n<3) return 0;
vector<int> leftHeight(n,0);
vector<int> rightHeight(n,0);
int water = 0;
for(int i=1; i<n; i++)
leftHeight[i] = max(leftHeight[i-1], A[i-1]);
for(int i=n-2; i>=0; i--) {
rightHeight[i] = max(rightHeight[i+1], A[i+1]);
int minHeight = min(leftHeight[i], rightHeight[i]);
if(minHeight>A[i]) water += (minHeight - A[i]);
}
return water;
}
};