Violence
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public int trap(int[] height) { int res = 0;
for (int i = 1; i < height.length - 1; i++) { int leftMax = 0, rightMax = 0;
for (int j = i - 1; j >= 0; j--) { leftMax = Math.max(height[j], leftMax); } for (int j = i + 1; j < height.length; j++) { rightMax = Math.max(height[j], rightMax); }
int minMax = Math.min(leftMax, rightMax); if (minMax > height[i]) { res += minMax - height[i]; } }
return res; } }
|
Violence
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| class Solution { public int trap(int[] height) { int res = 0;
for (int i = 1; i < height.length - 1; i++) { int leftMax = 0, rightMax = 0;
for (int j = i; j >= 0; j--) { leftMax = Math.max(height[j], leftMax); } for (int j = i; j < height.length; j++) { rightMax = Math.max(height[j], rightMax); }
res += Math.min(leftMax, rightMax) - height[i]; }
return res; } }
|
Iterate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public int trap(int[] height) { int[] leftMax = new int[height.length]; for (int i = 1; i < height.length; i++) { leftMax[i] = Math.max(leftMax[i - 1], height[i - 1]); }
int[] rightMax = new int[height.length]; for (int i = height.length - 2; i >= 0; i--) { rightMax[i] = Math.max(rightMax[i + 1], height[i + 1]); }
int water = 0;
for (int i = 1; i < height.length - 1; i++) { int min = Math.min(leftMax[i], rightMax[i]); water += Math.max(0, min - height[i]); }
return water; } }
|
Stack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Solution { public int trap(int[] height) { Stack<Integer> decreaseStack = new Stack<>(); int water = 0; for (int i = 0; i < height.length; i++) { while (!decreaseStack.isEmpty() && height[i] > height[decreaseStack.peek()]) { int midHeight = height[decreaseStack.pop()]; if (decreaseStack.isEmpty()) { break; } int leftIndex = decreaseStack.peek(); int leftHeight = height[leftIndex]; int rightHeight = height[i];
int width = i - leftIndex - 1; int h = Math.min(leftHeight, rightHeight) - midHeight; water += width * h; }
decreaseStack.push(i); }
return water; } }
|
栈中不存储相同的高度也能 AC,详见下方解法。
Stack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public int trap(int[] height) { int water = 0; Stack<Integer> decreaseStack = new Stack<>(); for (int i = 0; i < height.length; i++) { while (!decreaseStack.isEmpty() && height[i] >= height[decreaseStack.peek()]) { int midHeight = height[decreaseStack.pop()]; if (decreaseStack.isEmpty()) { break; } int leftIndex = decreaseStack.peek(); int width = i - leftIndex-1; int leftHeight = height[leftIndex]; water += (Math.min(leftHeight, height[i]) - midHeight) * width; }
decreaseStack.push(i); }
return water; } }
|
Two Pointers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public int trap(int[] height) { int water = 0;
int leftMax = 0, rightMax = 0; int i = 0, j = height.length - 1; while (i <= j) { if (leftMax <= rightMax) { water += Math.max(0, leftMax - height[i]); leftMax = Math.max(leftMax, height[i++]); } else { water += Math.max(0, rightMax - height[j]); rightMax = Math.max(rightMax, height[j--]); } }
return water; } }
|
Two Pointers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public int trap(int[] height) { int leftMax = 0; int rightMax = 0;
int i = 0, j = height.length - 1;
int water = 0; while (i <= j) { leftMax = Math.max(leftMax, height[i]); rightMax = Math.max(rightMax, height[j]);
if (leftMax <= rightMax) { water += leftMax - height[i++]; } else { water += rightMax - height[j--]; } }
return water; } }
|
References
42. Trapping Rain Water
官方题解看不懂? 双指针解法的清晰说明
面试题 17.21. 直方图的水量