Skip to content

Commit a51bee3

Browse files
committed
Add the solutions for leetcode problem 42
1 parent a0fe736 commit a51bee3

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package org.sean.array;
2+
3+
import java.util.ArrayDeque;
4+
import java.util.Deque;
5+
6+
// 42. Trapping Rain Water
7+
public class WaterBar {
8+
public int trap(int[] height) {
9+
if (height == null || height.length <= 1) return 0;
10+
11+
int max = 0;
12+
int maxWaterUnit = 0;
13+
Deque<Integer> stack = new ArrayDeque<>();
14+
int i = 0;
15+
while (i < height.length) {
16+
int n = height[i];
17+
if (stack.isEmpty() || height[stack.peek()] >= n) {
18+
stack.push(i);
19+
} else {
20+
int top = stack.pop();
21+
22+
// https://leetcode.com/problems/trapping-rain-water/discuss/17414/A-stack-based-solution-for-reference-inspired-by-Histogram
23+
// Optimization:
24+
// "use a stack that store the indices with decreasing bar height, once we find a bar who's height is
25+
// larger, then let the top of the stack be bot, the cur bar is ir, and the previous bar is il."
26+
maxWaterUnit = stack.isEmpty() ? 0 : (Math.min(height[stack.peek()], n) - height[top]) * (i - stack.peek() - 1);
27+
max += maxWaterUnit;
28+
i--;
29+
}
30+
i++;
31+
}
32+
33+
return max;
34+
}
35+
36+
public int trap0(int[] height) {
37+
if (height == null || height.length <= 1) return 0;
38+
39+
int sum = 0, i = 0;
40+
int len = height.length;
41+
42+
// Stack<Integer> stack = new Stack<>();
43+
// Deque is preferred.
44+
Deque<Integer> stack = new ArrayDeque<Integer>();
45+
46+
int inStackMax = 0;
47+
int inMaxIndex = 0;
48+
while (height[i] <= 0) i++;
49+
50+
51+
while (i < len) {
52+
int h = height[i];
53+
if (stack.isEmpty() || height[stack.peek()] >= h) {
54+
if (h > inStackMax) {
55+
inStackMax = h;
56+
inMaxIndex = i;
57+
}
58+
59+
stack.push(i);
60+
//System.out.println(String.format(">>> Pushed pos: %d, val : %d", i, height[i]));
61+
62+
} else { // h > s[top]
63+
int poppedCnt = 0;
64+
int completionIndex = i;
65+
int boardValue;
66+
while (!stack.isEmpty() && height[stack.peek()] < h) {
67+
if (stack.peek() == inMaxIndex) break;
68+
69+
poppedCnt++;
70+
int top = stack.pop();
71+
int elem = height[top];
72+
73+
boardValue = h;
74+
if (inStackMax < h) {
75+
completionIndex = inMaxIndex;
76+
boardValue = inStackMax;
77+
}
78+
79+
// Math.min(inStackMax, h)
80+
int trappedBlocks = boardValue - elem; // within the boarder
81+
sum += trappedBlocks;
82+
}
83+
84+
85+
// rePush the completed sections
86+
while (poppedCnt > 0) {
87+
stack.push(completionIndex);
88+
poppedCnt--;
89+
}
90+
91+
92+
// rePush current section
93+
stack.push(i);
94+
if (h > inStackMax) {
95+
inStackMax = h;
96+
inMaxIndex = i;
97+
}
98+
}
99+
i++;
100+
}
101+
return sum;
102+
}
103+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.sean.array;
2+
3+
import org.junit.Assert;
4+
import org.junit.Before;
5+
import org.junit.Test;
6+
7+
public class WaterBarTest {
8+
9+
private WaterBar waterBar;
10+
11+
@Before
12+
public void setUp() throws Exception {
13+
waterBar = new WaterBar();
14+
}
15+
16+
@Test
17+
public void testTrapWater() {
18+
int size = waterBar.trap(new int[]{0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1});
19+
Assert.assertEquals(6, size);
20+
21+
size = waterBar.trap(new int[]{4,2,0,3,2,5});
22+
Assert.assertEquals(9, size);
23+
}
24+
}

0 commit comments

Comments
 (0)