[leetcode]Trapping Rain Water

此题是道神题。一开始我也像参考链接http://www.cnblogs.com/lichen782/p/Leetcode_Trapping_Rain_Water.html里面一样想了许久想到“俄罗斯方块”想法。但复杂度不够好。

后来看了方法二,确实巧妙。“其实,本质上来说,第一步保障了左右两边的水总是能“放进去”,因为大板子在中间档着嘛。”

public class Solution {

    public int trap(int[] A) {

        // Start typing your Java solution below

        // DO NOT write main() function

        int len = A.length;

        if (len == 0) return 0;

        int maxIndex = 0;

        for (int i = 0; i < len; i++) {

            if (A[i] > A[maxIndex]) {

                maxIndex = i;

            }

        }       

        

        int water = 0;

        int curMax = 0;

        // left to max

        for (int i = 0; i < maxIndex; i++) {

            if (A[i] > curMax) {

                curMax = A[i];

            }

            else if (A[i] < curMax) {

                water += (curMax - A[i]);

            }

        }

        curMax = 0;

        // right to max

        for (int i = len - 1; i > maxIndex; i--) {

            if (A[i] > curMax) {

                curMax = A[i];

            }

            else if (A[i] < curMax) {

                water += (curMax - A[i]);

            }

        }

        

        return water;

    }

}

第二刷,用单调栈解决了,不过Annie的方法,找出两边的高点比较好:

int trap(int A[], int n) {

        stack<int> stk; // descending

        int result = 0;

        int i = 0;

        while (i < n) {

            if (stk.size() == 0 || A[stk.top()] > A[i]) {

                stk.push(i); // the index

                i++;

            } else { // A[i] >= stk.top();

                int j = stk.top();

                stk.pop();

                if (stk.size() != 0) {

                    result += (i - stk.top() - 1) * (min(A[stk.top()], A[i]) - A[j]);

                }

            }

        }

        return result;

    }

    

    // Solution: Find left bound and right bound for each element. O(n).

    int trap_1(int A[], int n) {

        if (n == 0) return 0;

        vector<int> maxLeft(n,0);

        vector<int> maxRight(n,0);

        maxLeft[0] = A[0];

        maxRight[n - 1] = A[n - 1];

        for (int i = 1; i < n; ++i) {

            maxLeft[i] = max(maxLeft[i - 1], A[i]);

            maxRight[n - 1 - i] = max(maxRight[n - i], A[n - 1 - i]);

        }

        

        int res = 0;

        for (int i = 1; i < n; ++i) {

            res += min(maxLeft[i], maxRight[i]) - A[i];

        }

        return res;

    }

  

你可能感兴趣的:(LeetCode)