是一种数据结构,用来处理一些不交集的合并和查询问题,即得到一系列没有重复元素的集合
满足:朋友的朋友就是我的朋友的原则,通过关系进行串联
遍历查找的效率不高,引入路径压缩,进行优化算法
连通分量
适用问题:
(1)图的连通性问题
(2)集合的个数:求得的是并查集中连通分量的数目
例题:岛屿数量
package Connect;
public class Solution2 {
class UnionFind{
int count;//集合的个数
int[] parent;//一个集合的根节点
int[] rank;//根节点的个数
public UnionFind(char[][] grid){
count = 0;
int m = grid.length;
int n = grid[0].length;
parent =new int[m*n];
rank = new int[m*n];
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;
count++;
}
rank[i*n+j] = 0;
}
}
}
public int find(int i){ //找父节点
if(parent[i] !=i){
parent[i] = find(parent[i]);
}
return parent[i];
}
public void union(int x, int y) {
int rootx = find(x);
int rooty = find(y);
if (rootx != rooty) {
if (rank[rootx] > rank[rooty]) {
parent[rooty] = rootx;
} else if (rank[rootx] < rank[rooty]) {
parent[rootx] = rooty;
} else {
parent[rooty] = rootx;
rank[rootx] += 1;
}
--count;
}
}
public int getCount() {
return count;
}
}
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int nr = grid.length;
int nc = grid[0].length;
int num_islands = 0;
UnionFind uf = new UnionFind(grid);
for (int r = 0; r < nr; ++r) {
for (int c = 0; c < nc; ++c) {
if (grid[r][c] == '1') {
grid[r][c] = '0';
if (r - 1 >= 0 && grid[r-1][c] == '1') {
uf.union(r * nc + c, (r-1) * nc + c);
}
if (r + 1 < nr && grid[r+1][c] == '1') {
uf.union(r * nc + c, (r+1) * nc + c);
}
if (c - 1 >= 0 && grid[r][c-1] == '1') {
uf.union(r * nc + c, r * nc + c - 1);
}
if (c + 1 < nc && grid[r][c+1] == '1') {
uf.union(r * nc + c, r * nc + c + 1);
}
}
}
}
return uf.getCount();
}
}
也可以用深度优先、广度优先实现,注意递归的返回值条件
/*
深度优先算法实现,也可以通过广度优先(队列)实现
*/
class Solution {
public int numIslands(char[][] grid) {
int count = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
count++;
dfs(grid,i,j);
}
}
}
return count;
}
public void dfs(char[][] grid, int m, int n) {
if (m >= grid.length || n >= grid[0].length || m < 0 || n < 0 || grid[m][n] == '0') {
return;
}
grid[m][n] = '0';
dfs(grid, m + 1, n);
dfs(grid, m - 1, n);
dfs(grid, m, n + 1);
dfs(grid, m, n - 1);
}
}