岛屿数量(bfs+并查集)

题目:

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

示例 2:

输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j] 的值为 '0' 或 '1'

思路:

看有多少个岛屿没有相连  想到利用并查集的方法来进行求解。

而怎么遍历其周围全部是1的结点呢?这里利用了bfs算法 把已经走过的那个点和通过它走到的那个点设置成一个祖先(注意 因为不确定起始点是哪一个点:所以需要开一个二重循环进行判断)

最后遍历p数组 统计有几个岛屿 

代码实现:

#include<bits/stdc++.h>
using namespace std; 
int n=4,m=5;
int maze[10][10];
int flag[10][10];//有没有判断过 
int p[100];//自己的父结点 
//栈
pair<int,int> q[100];
int tt,hh; 
//四个方向
int idx[4]={0,0,1,-1},idy[4]={1,-1,0,0};
int find(int x)
{
	if(p[x]!=x)
	p[x]=find(p[x]);
	return p[x];
}
void bfs(int x,int y)
{
	while(tt>hh)
	{
		pair<int,int>t=q[hh++];
		for(int i=0;i<4;i++)
		{
			int X,Y;
			X=t.first+idx[i];
			Y=t.second+idy[i];
			if(X<n&&X>=0&&Y>=0&&Y<m&&flag[X][Y]==0&&maze[X][Y]==1)
			{
				p[find(X*n+Y)]=find(t.first*n+t.second);//合并 
				flag[X][Y]=1;
				q[tt++]={X,Y};
			}
		}
	}
}
int main()
{
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			p[i*n+j]=i*n+j;
			cin>>maze[i][j];
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(maze[i][j]&&flag[i][j]==0)
			{ 
				tt=hh=0;
				q[tt++]={i,j};
				flag[i][j]=1;
				bfs(i,j);
			}
		}
	}
	int res=0;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(p[i*n+j]==i*n+j&&maze[i][j])
			{
				//cout<<i+1<<' '<<j+1<<endl;
				res++; 
			}
		}
	 } 
	 cout<<res<<endl;
	return 0;
}
/*
测试1
1 1 1 1 0
1 1 0 1 0
1 1 0 0 0
0 0 0 0 0  
*/
/*
测试2 
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0 
0 0 0 1 1 
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值