zoukankan      html  css  js  c++  java
  • [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;
        }
    

     Python3,单调栈

    class Solution:
        def trap(self, height: List[int]) -> int:
            stk = []
            area = 0
            for i in range(len(height)):
                h = height[i]
                last_height = 0
                while len(stk) > 0 and height[stk[len(stk) - 1]] <= h:
                    left_idx = stk.pop()
                    left_h = height[left_idx]
                    area += (left_h - last_height) * (i - left_idx - 1)
                    last_height = left_h
                if len(stk) > 0:
                    area += (h - last_height) * (i - stk[len(stk) - 1] - 1)
                stk.append(i)
                
            return area
                    
                
                    
    

      

  • 相关阅读:
    Codeforces Round #249 (Div. 2) D. Special Grid 枚举
    图论二
    C语言中的atan和atan2(转)
    BestCoder Round #79 (div.2)
    数学
    LCA
    二分图
    动态规划
    线段树
    树状数组
  • 原文地址:https://www.cnblogs.com/lautsie/p/3256142.html
Copyright © 2011-2022 走看看