此题是道神题。一开始我也像参考链接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