Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f142ca0

Browse files
ObiWanKeonitrekhleb
authored andcommitted
Add rain-terraces (trapping rain water) algorithm (trekhleb#112)
* Add rain-terraces (trapping rain water) algorithm * Fixed linting errors * Fixed linting errors
1 parent 97c9f6f commit f142ca0

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Rain Terraces (Trapping Rain Water) Problem
2+
3+
Given an array of non-negative integers representing terraces in an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
4+
5+
![Rain Terraces](https://www.geeksforgeeks.org/wp-content/uploads/watertrap.png)
6+
7+
## Examples
8+
9+
**Example #1**
10+
11+
```
12+
Input: arr[] = [2, 0, 2]
13+
Output: 2
14+
Structure is like below
15+
| |
16+
|_|
17+
We can trap 2 units of water in the middle gap.
18+
```
19+
20+
**Example #2**
21+
22+
```
23+
Input: arr[] = [3, 0, 0, 2, 0, 4]
24+
Output: 10
25+
Structure is like below
26+
|
27+
| |
28+
| | |
29+
|__|_|
30+
We can trap "3*2 units" of water between 3 an 2,
31+
"1 unit" on top of bar 2 and "3 units" between 2
32+
and 4. See below diagram also.
33+
```
34+
35+
**Example #3**
36+
37+
```
38+
Input: arr[] = [0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1]
39+
Output: 6
40+
|
41+
| || |
42+
_|_||_||||||
43+
Trap "1 unit" between first 1 and 2, "4 units" between
44+
first 2 and 3 and "1 unit" between second last 1 and last 2
45+
```
46+
47+
## Algorithms
48+
49+
50+
51+
## References
52+
53+
- [GeeksForGeeks](https://www.geeksforgeeks.org/trapping-rain-water/)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* @param {number[]} terraces
3+
* @return {number}
4+
*/
5+
6+
/*
7+
* STEPS
8+
* 1. Find the highest terraces on the left and right side of the elevation map:
9+
* e.g. [0, 2, 4, 3, 1, 2, 4, 0, 8, 7, 0] => (leftMax = 4, rightMax = 8)
10+
* This is because water will "trail off" the sides of the terraces.
11+
*
12+
* 2. At this point, we are essentially dealing with a new map: [4, 3, 4, 2, 4, 0, 8].
13+
* From here, we loop through the map from the left to the right (if leftMax > rightMax,
14+
* otherwise we move from right to left), adding water as we go unless we reach a value
15+
* that is greater than or equal to leftMax || rightMax.
16+
* e.g. [4, 3, 4, 2, 4, 0, 8]
17+
* ^
18+
* water += leftMax - 3 => water = 1
19+
* or if the terrace array was reversed:
20+
* e.g. [8, 0, 4, 2, 4, 3, 4]
21+
* ^
22+
* water += rightMax - 3 => water = 1
23+
*
24+
* 3. Again, we've essentially shortened the map: [4, 2, 4, 0, 8].
25+
* Now we repeat the above steps on the new array.
26+
* e.g.
27+
* Next Iteration:
28+
* [4, 2, 4, 0, 8]
29+
* ^
30+
* water += leftMax - 2 => water = 3
31+
*
32+
* Next Iteration:
33+
* [4, 0, 8]
34+
* ^
35+
* water += leftMax - 0 => water = 7
36+
*
37+
* return water(7)
38+
*/
39+
export default function rainTerraces(terraces) {
40+
let start = 0;
41+
let end = terraces.length - 1;
42+
let water = 0;
43+
let leftMax = 0;
44+
let rightMax = 0;
45+
46+
while (start < end) {
47+
// Loop to find left max
48+
while (start < end && terraces[start] <= terraces[start + 1]) {
49+
start += 1;
50+
}
51+
leftMax = terraces[start];
52+
53+
// Loop to find right max
54+
while (end > start && terraces[end] <= terraces[end - 1]) {
55+
end -= 1;
56+
}
57+
rightMax = terraces[end];
58+
59+
// Determine which direction we need to move in
60+
if (leftMax < rightMax) {
61+
// Move from left to right and collect water
62+
start += 1;
63+
while (start < end && terraces[start] <= leftMax) {
64+
water += leftMax - terraces[start];
65+
start += 1;
66+
}
67+
} else {
68+
// Move from left to right and collect water
69+
end -= 1;
70+
while (end > start && terraces[end] <= rightMax) {
71+
water += rightMax - terraces[end];
72+
end -= 1;
73+
}
74+
}
75+
}
76+
return water;
77+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import rainTerraces from '../rainTerraces';
2+
3+
describe('rainTerraces', () => {
4+
it('should find the amount of water collected after raining', () => {
5+
expect(rainTerraces([2, 0, 2])).toBe(2);
6+
expect(rainTerraces([3, 0, 0, 2, 0, 4])).toBe(10);
7+
expect(rainTerraces([0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1])).toBe(6);
8+
expect(rainTerraces([1, 1, 1, 1, 1])).toBe(0);
9+
expect(rainTerraces([1, 2, 3, 4, 5])).toBe(0);
10+
expect(rainTerraces([4, 1, 3, 1, 2, 1, 2, 1])).toBe(4);
11+
});
12+
});

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /