并查集(Disjointed Set)是一种非常精巧而且实用的数据结构,主要用于处理一些不相交集合的合并问题。
一、题目描述
二、样例
三、解题思路
1.求解步骤
利用并查集(数组a)记录连通的陆地,注意传入数组类型是char。
1,预处理并查集数组。
2,扫描grid数组,对陆地进行“向上、向左”的连通判定(注意小于0越界),一旦连通调用并查集合并函数更新。
3,扫描数组a,满足a[i][j]==i*n+j的点即可代表一个连通的陆地,因为递归查找并查集的根节点一定满足该式,不满足该式但属于同一连通块的可以不必记录。
2.AC代码
代码如下(C++):
class Solution {
public:
int a[310][310];//并查集
int m,n;
void init_set()//初始化并查集,将二维坐标映射到一个整数
{
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
a[i][j]=i*n+j;
}
int find_set(int x)//并查集递归查找函数
{
int xx=x/n;
int yy=x%n;
return a[xx][yy]==x?x:find_set(a[xx][yy]);
}
void union_set(int x,int y)//并查集合并
{
x=find_set(x);
y=find_set(y);
if(x!=y){ int xx1=x/n,yy1=x%n;
int xx2=y/n,yy2=y%n;
a[xx1][yy1]=a[xx2][yy2];}
}
int numIslands(vector<vector<char>>& grid) {
m=grid.size();
n=grid[0].size();
init_set();
for(int i=0;i<m;i++)//扫描grid数组并合并连通岛屿
for(int j=0;j<n;j++)
{
if(grid[i][j]=='1')
{
if(j>0)
{
if(grid[i][j-1]=='1')union_set(a[i][j-1],a[i][j]);
}
if(i>0)
{
if(grid[i-1][j]=='1')union_set(a[i-1][j],a[i][j]);
}
}
}
int ans=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
if(grid[i][j]=='1'&&a[i][j]==i*n+j)ans++;//若属于同一岛屿,则递归最终找到的根节点一定满足该式,只判断根节点
return ans;
}
};
3.提交结果
总结
以上就是关于LeetCode 200. 岛屿数量 C++ 并查集的全部内容。