Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it can trap after raining.
Example 1:
1 2 3
Input: height = [0,1,0,2,1,0,1,3,2,1,2,1] Output: 6 Explanation: The above elevation map (black section) is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.
publicinttrap(int[] height){ // find the maximum num in the height int max = Integer.MIN_VALUE; for (int i : height) { if (i > max) max = i; } int res = 0; for (int i = 1; i <= max; i++) { int count = 0; boolean start = false; for (int value : height) { if (start && value < i) { count++; }
if (value >= i) { res += count; count = 0; start = true; } } } return res; }
publicinttrap(int[] height){ // 2. column int count = 0; for (int i = 0; i < height.length; i++) { int minColumn = getMinColumn(i, height); if (minColumn > height[i]) { count += (minColumn - height[i]); } } return count; }
privateintgetMinColumn(int index, int[] height){ int left = 0, right = 0; for (int i = 0; i < index; i++) { if (height[i] > left) left = height[i]; } for (int i = index + 1; i < height.length; i++) { if (height[i] > right) right = height[i]; } return Math.min(left, right); }
时间复杂度:O(n^2)
空间复杂度:O(1)
思路三:栈
可以想象为括号匹配:其中墙可以看作括号,水可以看作括号匹配的中间计算
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
publicinttrap(int[] height){ // 3. Stack Stack<Integer> stack = new Stack<>(); int res = 0; int cur = 0; while (cur < height.length) { while (!stack.isEmpty() && height[cur] > height[stack.peek()]) { int temp = height[stack.peek()]; stack.pop(); if (stack.isEmpty()) break; int len = cur - stack.peek() - 1; int min = Math.min(height[cur], height[stack.peek()]); res += (min - temp) * len; } stack.push(cur); cur++; } return res; }
publicinttrap(int[] height){ int res = 0; int[] left = newint[height.length]; int[] right = newint[height.length];
// use array to save the maximum left num of every item for (int i = 1; i < height.length - 1; i++) { left[i] = Math.max(left[i - 1], height[i - 1]); }
// use array to save the maximum right num of every item for (int i = height.length - 2; i >= 0; i--) { right[i] = Math.max(right[i + 1], height[i + 1]); }
for (int i = 0; i < height.length; i++) { int minColumn = Math.min(left[i], right[i]); if (minColumn > height[i]) { res += minColumn - height[i]; } } return res; }