并查集
class UnionFind {
public:
UnionFind(vector<vector<char>>& grid) {
int m = grid.size(), n = grid[0].size();
parent.assign(m * n, 0);
rank.assign(m* n, 0);
count = 0; // 注意先初始为0
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;
rank[i * n + j] = 1;
++count; // 陆地块数计数
} else {
parent[i * n + j] = -1; // 其实可以不加
}
}
}
}
int find(int x) {
if (x != parent[x]) {
parent[x] = find(parent[x]); // 路径压缩,递归查询
}
return parent[x];
}
void unite (int a, int b) {
int parentA = find(a);
int parentB = find(b);
if (parentA != parentB) {
if (rank[parentA] > rank[parentB]) { // 按秩合并
parent[parentB] = parentA;
} else if (rank[parentA] < rank[parentB]) {
parent[parentA] = parentB;
} else {
parent[parentB] = parentA;
rank[parentB]++;
}
--count;
}
}
int getCount() const {
return count;
}
private:
vector<int> parent;
vector<int> rank;
int count;
};
class Solution {
public:
/**
* 判断岛屿数量
* @param grid char字符型vector<vector<>>
* @return int整型
*/
int solve(vector<vector<char> >& grid) {
// write code here
int m = grid.size();
if (m == 0) return 0;
int n = grid[0].size();
UnionFind uf(grid); // 类初始化
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (grid[i][j] == '1') {
grid[i][j] = '0';
if (i > 0 && grid[i - 1][j] == '1') uf.unite(i * n + j, (i - 1) * n + j);
if (i + 1 < m && grid[i + 1][j] == '1') uf.unite(i * n + j, (i + 1) * n + j);
if (j > 0 && grid[i][j - 1] == '1') uf.unite(i * n + j, i * n + j - 1);
if (j + 1 < n && grid[i][j + 1] == '1') uf.unite(i * n + j, i * n + j + 1);
}
}
}
return uf.getCount();
}
};