Skip to content

Commit d2241ba

Browse files
authored
Create shortest-bridge.cpp
1 parent f90ae36 commit d2241ba

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

C++/shortest-bridge.cpp

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// Time: O(n^2)
2+
// Space: O(n^2)
3+
4+
class Solution {
5+
public:
6+
template <typename T>
7+
struct PairHash {
8+
size_t operator()(const pair<T, T>& p) const {
9+
size_t seed = 0;
10+
seed ^= std::hash<T>{}(p.first) + 0x9e3779b9 + (seed<<6) + (seed>>2);
11+
seed ^= std::hash<T>{}(p.second) + 0x9e3779b9 + (seed<<6) + (seed>>2);
12+
return seed;
13+
}
14+
};
15+
16+
int shortestBridge(vector<vector<int>>& A) {
17+
static const vector<pair<int, int>> directions{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
18+
19+
unordered_set<pair<int, int>, PairHash<int>> lookup;
20+
unordered_set<pair<int, int>, PairHash<int>> target;
21+
auto islands = get_islands(A);
22+
lookup = move(islands[0]);
23+
target = move(islands[1]);
24+
queue<pair<pair<int, int>, int>> q;
25+
for (const auto& node : lookup) {
26+
q.emplace(node, 0);
27+
}
28+
while (!q.empty()) {
29+
pair<int, int> node;
30+
int dis;
31+
tie(node, dis) = q.front(); q.pop();
32+
if (target.count(node)) {
33+
return dis - 1;
34+
}
35+
for (const auto& d : directions) {
36+
pair<int, int> nei = make_pair(node.first + d.first, node.second + d.second);
37+
if (0 > nei.first || nei.first >= A.size() ||
38+
0 > nei.second || nei.second >= A[0].size() ||
39+
lookup.count(nei)) {
40+
continue;
41+
}
42+
q.emplace(nei, dis + 1);
43+
lookup.emplace(nei);
44+
}
45+
}
46+
}
47+
48+
private:
49+
vector<unordered_set<pair<int, int>, PairHash<int>>> get_islands(const vector<vector<int>>& A) {
50+
static const vector<pair<int, int>> directions{{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
51+
52+
vector<unordered_set<pair<int, int>, PairHash<int>>> islands;
53+
unordered_set<pair<int, int>, PairHash<int>> done;
54+
for (int r = 0; r < A.size(); ++r) {
55+
for (int c = 0; c < A[0].size(); ++c) {
56+
if (A[r][c] == 0 || done.count(make_pair(r, c))) {
57+
continue;
58+
}
59+
vector<pair<int, int>> s{{r, c}};
60+
unordered_set<pair<int, int>, PairHash<int>> lookup(s.cbegin(), s.cend());
61+
while (!s.empty()) {
62+
auto node = s.back(); s.pop_back();
63+
for (const auto& d : directions) {
64+
pair<int, int> nei = make_pair(node.first + d.first, node.second + d.second);
65+
if (0 > nei.first || nei.first >= A.size() ||
66+
0 > nei.second || nei.second >= A[0].size() ||
67+
lookup.count(nei) || A[nei.first][nei.second] == 0) {
68+
continue;
69+
}
70+
s.emplace_back(nei);
71+
lookup.emplace(nei);
72+
}
73+
}
74+
for (const auto& node : lookup) {
75+
done.emplace(node);
76+
}
77+
islands.emplace_back(move(lookup));
78+
if (islands.size() == 2) {
79+
break;
80+
}
81+
}
82+
}
83+
return islands;
84+
}
85+
};

0 commit comments

Comments
 (0)