经典的dfs/bfs问题,给一个起点开始搜索,满足条件则继续调用dfs/bfs
从没有访问过的某个陆地出发,将所有能到达的陆地的状态都记录为已访问。下次出发不从已访问的陆地出发,每次出发前都把岛屿数 + 1即可
class Solution {
public:
vector<vector<bool>> is_visited;
const vector<pair<int, int>> direction = {{1, 0}, {0, -1}, {-1, 0}, {0, 1}};
int m_;
int n_;
bool is_valid(int x, int y){
return x >= 0 && x < m_ && y >= 0 && y < n_;
}
void dfs(const vector<vector<char>>& grid, int i, int j) {
is_visited[i][j] = true;
for (auto d : direction) {
int x = i + d.first;
int y = j + d.second;
if (is_valid(x, y) && !is_visited[x][y] && grid[x][y] == '1') {
dfs(grid, x, y);
}
}
}
int numIslands(vector<vector<char>>& grid) {
m_ = grid.size();
n_ = grid[0].size();
is_visited.resize(m_, vector<bool>(n_, false));
int ans = 0;
for(int i = 0; i < m_; i++){
for(int j = 0; j < n_; j++){
if(!is_visited[i][j] && grid[i][j] == '1'){
dfs(grid, i, j);
ans++;
}
}
}
return ans;
}
};
遍历二维数组,合并不同的坐标时,在每个陆地坐标处查看自己右侧和下方的位置是否是陆地,如果是,合并当前陆地和自己右侧或下方的陆地
遍历完成后,并查集构造完成,直接获取并查集的集合数即可
class UnionFind{
public:
UnionFind(const vector<vector<char>>& grid){
m_ = grid.size();
n_ = grid[0].size();
for(int i = 0; i < m_; i++){
for(int j = 0; j < n_; j++){
if(grid[i][j] == '1') parent[i * n_ + j] = i * n_ + j;
}
}
}
int find_root(int x){
// x不存在于并查集
if(parent.find(x) == parent.end()) return -1;
if(x == parent[x]) return x;
parent[x] = find_root(parent[x]);
return parent[x];
}
void merge(int x, int y){
x = find_root(x);
y = find_root(y);
if(x != y) parent[x] = y;
}
int get_find_num() {
unordered_set<int> st;
// 遍历并查集,得到集合数量
for (auto iter = parent.begin(); iter != parent.end(); iter++) {
st.insert(find_root((*iter).first));
}
return st.size();
}
private:
unordered_map<int, int> parent; // 并查集
int m_;
int n_;
};
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
UnionFind uf(grid);
int m = grid.size();
int n = grid[0].size();
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
// 如果自己右边或者下面是陆地,则合并集合
if(grid[i][j] == '0') continue;
if(i < m - 1){
// 可以查看下方
if(grid[i + 1][j] == '1') uf.merge(i * n + j, (i + 1) * n + j);
}
if(j < n - 1){
// 可以查看右边
if(grid[i][j + 1] == '1') uf.merge(i * n + j, i * n + (j + 1));
}
}
}
return uf.get_find_num();
}
};