forked from Pr8862/pr_hacktoberfest-2k22
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path200. Number of Islands.cpp
128 lines (108 loc) · 3.76 KB
/
200. Number of Islands.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
//Runtime: 44 ms, faster than 7.77% of C++ online submissions for Number of Islands.
//Memory Usage: 12.2 MB, less than 12.36% of C++ online submissions for Number of Islands.
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int m = grid.size();
if(m == 0) return 0;
int n = grid[0].size();
queue<vector<int>> q;
int i = 0;
vector<vector<int>> dirs = {
{1,0},
{-1,0},
{0,1},
{0,-1}
};
vector<vector<bool>> visited(m, vector(n, false));
int ans = 0;
while(i < m*n){
while(i < m*n && !(!visited[i/n][i%n] && grid[i/n][i%n] == '1')){
i++;
}
if(i >= m*n) break;
// cout << i/n << " " << i%n << endl;
visited[i/n][i%n] = true;
q.push({i/n, i%n});
ans++;
//visite all cell connected to it
while(!q.empty()){
vector<int> cur = q.front(); q.pop();
int curI = cur[0], curJ = cur[1];
// cout << "cur: " << curI << " " << curJ << endl;
for(vector<int>& dir : dirs){
int newI = curI + dir[0];
int newJ = curJ + dir[1];
if(newI >= 0 && newI < m && newJ >= 0 && newJ < n && !visited[newI][newJ] && grid[newI][newJ] == '1'){
visited[newI][newJ] = true;
q.push({newI, newJ});
}
}
}
}
// cout << endl << endl;
return ans;
}
};
//Union Find
//Runtime: 24 ms, faster than 16.98% of C++ online submissions for Number of Islands.
//Memory Usage: 9.1 MB, less than 100.00% of C++ online submissions for Number of Islands.
class DSU{
public:
vector<int> parent;
DSU(int n){
parent= vector<int>(n);
iota(parent.begin(), parent.end(), 0);
};
int find(int x){
if(parent[x] != x){
parent[x] = find(parent[x]);
}
return parent[x];
};
void unite(int x, int y){
// parent[x] = find(parent[y]);
// parent[y] = find(parent[x]);
parent[find(x)] = find(y);
};
};
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
int m = grid.size();
if(m == 0) return 0;
int n = grid[0].size();
vector<vector<int>> dirs = {
{1,0},
{-1,0},
{0,1},
{0,-1}
};
DSU dsu(m*n);
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
// cout << "cur: " << i << " " << j << endl;
if(grid[i][j] != '1') continue;
for(vector<int>& dir : dirs){
int newI = i + dir[0];
int newJ = j + dir[1];
if(newI >= 0 && newI < m && newJ >= 0 && newJ < n && grid[newI][newJ] == '1'){
// cout << newI << " " << newJ << endl;
dsu.unite(i*n+j, newI*n+newJ);
// cout << "(" << i << ", " << j << ", " << dsu.parent[i*n+j] << "), (" << newI << ", " << newJ << ", " << dsu.parent[newI*n+newJ] << ")" << endl;
}
}
}
}
set<int> uniqParent;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(grid[i][j] == '1'){
// cout << i << " " << j << " " << dsu.find(i*n+j) << endl;
uniqParent.insert(dsu.find(i*n+j));
}
}
}
return uniqParent.size();
}
};