建立并查集
所谓并查集就是将想关联的物体联系成一个整体。
要建立并查集,我们通常需要两个数组,parent[]和rank[]
其中parent[i]表示i的父结点,rank[i]表示以i为结点的最远距离。
大家如果还是不了解的话,建议去B站搜索up主正月点灯笼的讲解视频,讲得非常清楚
下面就是一道典型的并查集例题;
https://leetcode-cn.com/problems/number-of-islands/

class Solution {
public:
vector<int> parent;//记录父结点
vector<int> rank;//记录以该点为父结点子链的最大长度
int len1;
int len2;
int z;
void init(vector<vector<char>>& grid)//初始化
{
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(grid[i][j]=='1')
{
++z;//先把所有1看为一个连通区域
parent.push_back(i*len2+j);//这里巧妙把二维转化为一维
}
else parent.push_back(-1);//如果是海域就输入-1
rank.push_back(0);
}
}
}
int Findroot(int x)//找父结点
{
while(x!=parent[x])
{
x=parent[x];
}
return x;
}
void Union(int x,int y)
{
int ix=Findroot(x);
int iy=Findroot(y);
if(ix==iy) return;
if(rank[ix]>rank[iy])//为了能快速找到父结点,我们总让子链长度大的当父结点
{
parent[iy]=ix;
}
else if(rank[ix]<rank[iy])
{
parent[ix]=iy;
}
else
{
++rank[ix];//一样长就随便选一个,并让那个子链长度+1
parent[iy]=ix;
}
--z;
}
int numIslands(vector<vector<char>>& grid) {
len1=grid.size();
if(len1==0) return 0;
len2=grid[0].size();
z=0;
init(grid);
for(int i=0;i<len1;i++)
{
for(int j=0;j<len2;j++)
{
if(grid[i][j]=='1')
{ grid[i][j]='0';
if(j>0&&grid[i][j-1]=='1') Union(i*len2+j,i*len2+j-1);
if(j+1<len2&&grid[i][j+1]=='1') Union(i*len2+j,i*len2+j+1);
if(i>0&&grid[i-1][j]=='1') Union(i*len2+j,(i-1)*len2+j);
if(i+1<len1&&grid[i+1][j]=='1') Union(i*len2+j,(i+1)*len2+j);
}
}
}
return z;
}
};

浙公网安备 33010602011771号