Leetcode: 42. Trapping Rain Water

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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章