forked from kamyu104/LintCode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
trapping-rain-water-ii.cpp
153 lines (134 loc) · 4.92 KB
/
trapping-rain-water-ii.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
144
145
146
147
148
149
150
151
152
153
// Time: O(m * n * (logm + logn))
// Space: O(m * n)
// BFS with priority queue (min heap), refactored version.
class Solution {
public:
struct Cell {
int i;
int j;
int height;
};
struct Compare {
bool operator()(const Cell& a, const Cell& b) {
return a.height > b.height;
}
};
/**
* @param heights: a matrix of integers
* @return: an integer
*/
int trapRainWater(vector<vector<int>> &heights) {
// Init m_, n_, is_visited_.
m_ = heights.size();
n_ = heights[0].size();
is_visited_ = vector<vector<bool>>(m_, vector<bool>(n_, false));
int trap = 0;
// Put the cells on the border into min heap.
for (int i = 0; i < m_; ++i) {
heap_.emplace(Cell{i, 0, heights[i][0]});
heap_.emplace(Cell{i, n_ - 1, heights[i][n_ - 1]});
}
for (int j = 0; j < n_; ++j) {
heap_.emplace(Cell{0, j, heights[0][j]});
heap_.emplace(Cell{m_ - 1, j, heights[m_ - 1][j]});
}
// BFS with priority queue (min heap)
while (!heap_.empty()) {
Cell c = heap_.top();
heap_.pop();
is_visited_[c.i][c.j] = true;
trap += fill(heights, c.i + 1, c.j, c.height); // Up
trap += fill(heights, c.i - 1, c.j, c.height); // Down
trap += fill(heights, c.i, c.j + 1, c.height); // Right
trap += fill(heights, c.i, c.j - 1, c.height); // Left
}
return trap;
}
int fill(vector<vector<int>>& heights, int i, int j, int height) {
// Out of border.
if ( i < 0 || i >= m_ || j < 0 || j >= n_) {
return 0;
}
// Fill unvisited cell.
if (!is_visited_[i][j]) {
is_visited_[i][j] = true; // Marked as visited.
heap_.emplace(Cell{i, j, max(height, heights[i][j])});
return max(0, height - heights[i][j]); // Fill in the gap.
}
return 0;
}
private:
int m_;
int n_;
vector<vector<bool>> is_visited_;
priority_queue<Cell ,vector<Cell>, Compare> heap_; // Use min heap to get the lowerest cell.
};
// Time: O(m * n * (logm + logn))
// Space: O(m * n)
// BFS with priority queue (min heap)
class Solution2 {
public:
struct Cell {
int i;
int j;
int height;
};
/**
* @param heights: a matrix of integers
* @return: an integer
*/
int trapRainWater(vector<vector<int>> &heights) {
const int m = heights.size();
const int n = heights[0].size();
int trap = 0;
vector<vector<bool>> is_visited(m, vector<bool>(n, false));
// Use min heap to get the lowerest Cell.
auto comp = [](const Cell& a, const Cell& b ) { return a.height > b.height; };
priority_queue<Cell , vector<Cell>, decltype(comp)> heap(comp);
// Put the Cells on the border into min heap.
for (int i = 0; i < m; ++i) {
heap.emplace(Cell{i, 0, heights[i][0]});
heap.emplace(Cell{i, n - 1, heights[i][n - 1]});
}
for (int j = 0; j < n; ++j) {
heap.emplace(Cell{0, j, heights[0][j]});
heap.emplace(Cell{m - 1, j, heights[m - 1][j]});
}
// BFS with priority queue (min heap)
while (!heap.empty()) {
// Get the lowest Cell.
Cell c = heap.top();
heap.pop();
is_visited[c.i][c.j] = true;
// Up
if (c.i + 1 < m && !is_visited[c.i + 1][c.j]) {
is_visited[c.i + 1][c.j] = true;
trap += max(0, c.height - heights[c.i + 1][c.j]); // Fill in the gap.
heap.emplace(Cell{c.i + 1, c.j, max(c.height,
heights[c.i + 1][c.j])});
}
// Down
if (c.i - 1 >= 0 && !is_visited[c.i - 1][c.j]) {
is_visited[c.i - 1][c.j] = true;
trap += max(0, c.height - heights[c.i - 1][c.j]); // Fill in the gap.
heap.emplace(Cell{c.i - 1, c.j, max(c.height,
heights[c.i - 1][c.j])});
}
// Right
if (c.j + 1 < n && !is_visited[c.i][c.j + 1]) {
is_visited[c.i][c.j + 1] = true;
trap += max(0, c.height - heights[c.i][c.j + 1]); // Fill in the gap.
heap.emplace(Cell{c.i, c.j + 1, max(c.height,
heights[c.i][c.j + 1])});
}
// Left
if (c.j - 1 >= 0 && !is_visited[c.i][c.j - 1]) {
is_visited[c.i][c.j - 1] = true;
trap += max(0, c.height - heights[c.i][c.j - 1]); // Fill in the gap.
heap.emplace(Cell{c.i, c.j - 1, max(c.height,
heights[c.i][c.j - 1])});
}
}
return trap;
}
};