并查集相关问题(自我回顾)
并查集的作用
并查集是一种利用一维数组而构成的模板类,在判断图的连通,岛屿数量等问题有着十分关键的作用,并且并查集的使用和构建也非常简单
并查集的构建
class bincha{
//数据总数
int n;
//记录当前独立的个体数量,每合并一次,setCount--
int setCount;
//每个数据的同类代表节点
int[] parent;
//每个同类数据集的数量,初始size都是1,x和y合并之后,其中一个数size[x]+=size[y],size[y]=0
int[] size;
//初始化并查集
public bincha(int n){
this.n = n;
this.setCount = n;
for (int i = 0; i < n; i++ ) {
parent[i] = i;
}
Arrays.fill(size, 1);
}
//找同类代表节点
public int find(int x){
//注意,写成parent[x] = find(parent[x])是为了及时更新同类节点,方便更快速查找,其实也可以只写find(parent[x])
return parent[x] == x ? x : parent[x] = find(parent[x]);
}
//合并数据集
public boolean unite(int x, int y){
x = find(x);
y = find(y);
if (x == y){
//同类节点,不需要合并
return false;
}
//合并优化操作,我们规定,合并的时候,总是将小数据集合并到大数据集
if(size[x] < size[y]) {
int temp = y;
y = x;
x = temp;
}
//合并
parent[y] = x;
size[x] += size[y];
size[y] = 0;
setCount--;
}
//判断两个数据是否连接
public boolean connected(int x, int y){
x = find(x);
y = find(y);
return x==y;
}
}
并查集的应用
1.岛屿问题 给定一个二维数组,0表示海,1表示陆地,求岛屿数量或者最大岛屿大小
我们可以将二维数组表示成一维数组的形式,一维数组的下标即为二维数组的横坐标乘纵向宽度+纵坐标。 初始化并查集,注意,0的地方size也为0,1的地方size为1。其他初始化方法不变。
从左至右,从上至下遍历二维数组,遇到1,就找其是否有正上方及正左方的1,有的话,合并,没有的话就不做操作。
2.图的连通问题 给定一个二维数组,表示边
同样构建一个大小为n的并查集(n为点的个数),遍历二维数组,unite(i,grid[i]中的每一个数)。
3.二分图问题 给定一个二维数组,表示边
同样构建一个大小为n的并查集(n为点的个数),遍历二维数组,connected(i,grid[i]中的每一个数),因为一条边的两个点不能在同一个集,如果connected方法返回true,直接判错。如果没有返回true,再unite(grid[i][0],grid[i]中的每一个数)。因为同一个点的多个邻接点肯定在一个集。