-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathtrapping_rain_water.cpp
143 lines (109 loc) · 4.27 KB
/
trapping_rain_water.cpp
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// # Non optimal solution... we dont need aux arrays to keep track of leftMax and rightMax
// # class Solution {
// # public:
// # int trap(vector<int>& height) {
// # if(height.size() == 0) return 0;
// # int n = height.size();
// # int leftMax[n], rightMax[n];
// # leftMax[0] = height[0];
// # rightMax[n-1] = height[n-1];
// # for(int i=1; i<n; i++) {
// # leftMax[i] = max(height[i], leftMax[i-1]);
// # }
// # for(int i=n-2; i>=0; i--) {
// # rightMax[i] = max(height[i], rightMax[i+1]);
// # }
// # int totalWater = 0;
// # for(int i=0; i<n; i++) {
// # totalWater += min(leftMax[i], rightMax[i]) - height[i];
// # }
// # return totalWater;
// # }
// # };
// class Solution:
// def trap(self, height: List[int]) -> int:
// left, right = 0, len(height) - 1
// maxLeft, maxRight = 0, 0
// waterTrap = 0
// while left <= right:
// if height[left] <= height[right]:
// if height[left] > maxLeft:
// maxLeft = height[left]
// else:
// waterTrap += maxLeft - height[left]
// left += 1
// else:
// if height[right] > maxRight:
// maxRight = height[right]
// else:
// waterTrap += maxRight - height[right]
// right -= 1
// return waterTrap
class Solution {
public:
int trap(vector<int>& height) {
//Method 1: Use two arrays to keep track of maxToLeft and maxToRight
/*
int n = height.size();
if(n == 0) return 0;
vector<int> maxToRight(n), maxToLeft(n);
int waterTrap = 0;
maxToLeft[0] = height[0];
for(int i = 1; i < n; i++) {
maxToLeft[i] = max(height[i], maxToLeft[i - 1]);
}
maxToRight[n - 1] = height[n - 1];
for(int i = n - 2; i >= 0; i--) {
maxToRight[i] = max(height[i], maxToRight[i + 1]);
}
for(int i = 0 ; i < n; i++) {
waterTrap += min(maxToLeft[i], maxToRight[i]) - height[i];
}
return waterTrap;
*/
//Method 2: Use two pointers left and right (instead of ararys) to keep track of maxToLeft and maxToRight
/*
int left = 0, right = height.size() - 1;
int maxLeft = 0, maxRight = 0, waterTrap = 0;
while(left <= right) {
if(height[left] <= height[right]) {
if(height[left] > maxLeft)
maxLeft = height[left];
else
waterTrap += maxLeft - height[left];
left++;
}
else {
if(height[right] > maxRight)
maxRight = height[right];
else
waterTrap += maxRight - height[right];
right--;
}
}
return waterTrap;
*/
//Method 3: Least intuitive - using stack
int length = height.size();
int verticalHeight, leftBound, horizontalWidth, waterTrap = 0, currentIndex, prevTop;
stack<int> indexes;
int i = 0;
while(i < length) {
currentIndex = i;
//found a increasing sequence - calculate maxArea
while(!indexes.empty() and height[currentIndex] > height[indexes.top()]) {
prevTop = height[indexes.top()];
indexes.pop();
if(indexes.empty())
break;
horizontalWidth = currentIndex - indexes.top() - 1;
verticalHeight = min(height[currentIndex], height[indexes.top()]) - height[prevTop];
waterTrap += verticalHeight * horizontalWidth;
}
//when its strictly monotonically decreasing sequence of heights
indexes.push(currentIndex);
i++;
}
return waterTrap;
}
};