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 145111c

Browse files
kanavgoyal898realstealthninja
andauthored
feat: implement optimized two-pointer approach for trapping rainwater (TheAlgorithms#2975) (TheAlgorithms#2976)
* feat: optimize trapping rainwater * incorporate changes --------- Co-authored-by: realstealthninja <68815218+realstealthninja@users.noreply.github.com>
1 parent 79aeaa9 commit 145111c

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/**
2+
* @file
3+
* @brief Implementation of the [Trapped Rainwater
4+
* Problem](https://www.geeksforgeeks.org/trapping-rain-water/)
5+
* @details
6+
* This implementation calculates the total trapped rainwater using a
7+
* two-pointer approach. It maintains two pointers (`left` and `right`) and
8+
* tracks the maximum height seen so far from both ends (`leftMax` and
9+
* `rightMax`). At each step, the algorithm decides which side to process based
10+
* on which boundary is smaller, ensuring O(n) time and O(1) space complexity.
11+
* @author [kanavgoyal898](https://github.com/kanavgoyal898)
12+
*/
13+
14+
#include <algorithm> /// For std::min and std::max
15+
#include <cassert> /// For assert
16+
#include <cstddef> /// For std::size_t
17+
#include <cstdint> /// For std::uint32_t
18+
#include <vector> /// For std::vector
19+
20+
/*
21+
* @namespace
22+
* @brief Dynamic Programming Algorithms
23+
*/
24+
namespace dynamic_programming {
25+
/**
26+
* @brief Function to calculate the trapped rainwater
27+
* @param heights Array representing the heights of walls
28+
* @return The amount of trapped rainwater
29+
*/
30+
uint32_t trappedRainwater(const std::vector<uint32_t>& heights) {
31+
std::size_t n = heights.size();
32+
if (n <= 2)
33+
return 0; // Not enough walls to trap water
34+
35+
std::size_t left = 0, right = n - 1;
36+
uint32_t leftMax = 0, rightMax = 0, trappedWater = 0;
37+
38+
// Traverse from both ends towards the center
39+
while (left < right) {
40+
if (heights[left] < heights[right]) {
41+
// Water trapped depends on the tallest wall to the left
42+
if (heights[left] >= leftMax)
43+
leftMax = heights[left]; // Update left max
44+
else
45+
trappedWater +=
46+
leftMax - heights[left]; // Water trapped at current left
47+
++left;
48+
} else {
49+
// Water trapped depends on the tallest wall to the right
50+
if (heights[right] >= rightMax)
51+
rightMax = heights[right]; // Update right max
52+
else
53+
trappedWater +=
54+
rightMax -
55+
heights[right]; // Water trapped at current right
56+
--right;
57+
}
58+
}
59+
60+
return trappedWater;
61+
}
62+
63+
} // namespace dynamic_programming
64+
65+
/**
66+
* @brief Self-test implementations
67+
* @returns void
68+
*/
69+
static void test() {
70+
std::vector<uint32_t> test_basic = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
71+
assert(dynamic_programming::trappedRainwater(test_basic) == 6);
72+
73+
std::vector<uint32_t> test_peak_under_water = {3, 0, 2, 0, 4};
74+
assert(dynamic_programming::trappedRainwater(test_peak_under_water) == 7);
75+
76+
std::vector<uint32_t> test_bucket = {5, 1, 5};
77+
assert(dynamic_programming::trappedRainwater(test_bucket) == 4);
78+
79+
std::vector<uint32_t> test_skewed_bucket = {4, 1, 5};
80+
assert(dynamic_programming::trappedRainwater(test_skewed_bucket) == 3);
81+
82+
std::vector<uint32_t> test_empty = {};
83+
assert(dynamic_programming::trappedRainwater(test_empty) == 0);
84+
85+
std::vector<uint32_t> test_flat = {0, 0, 0, 0, 0};
86+
assert(dynamic_programming::trappedRainwater(test_flat) == 0);
87+
88+
std::vector<uint32_t> test_no_trapped_water = {1, 1, 2, 4, 0, 0, 0};
89+
assert(dynamic_programming::trappedRainwater(test_no_trapped_water) == 0);
90+
91+
std::vector<uint32_t> test_single_elevation = {5};
92+
assert(dynamic_programming::trappedRainwater(test_single_elevation) == 0);
93+
94+
std::vector<uint32_t> test_two_point_elevation = {5, 1};
95+
assert(dynamic_programming::trappedRainwater(test_two_point_elevation) ==
96+
0);
97+
98+
std::vector<uint32_t> test_large_elevation_map_difference = {5, 1, 6, 1,
99+
7, 1, 8};
100+
assert(dynamic_programming::trappedRainwater(
101+
test_large_elevation_map_difference) == 15);
102+
}
103+
104+
/**
105+
* @brief Main function
106+
* @returns 0 on exit
107+
*/
108+
int main() {
109+
test(); // run self-test implementations
110+
return 0;
111+
}

0 commit comments

Comments
(0)

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