题目内容
给你一个由 ‘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'
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-islands
c语言解答(并查集)
/*
思路:
并查集:两个for循环遍历整个网格,然后找到一个1后,遍历其上下左右,找到的1重新置于0,用count组合.
二维坐标转一维坐标方式
a[i][j]=a[i*每行元素个数+j];
二维转成一维后就容易用并查集了
*/
int numIslands(char** grid, int gridSize, int* gridColSize){
//cout统计岛屿数量
int count=0;
//定义行
int R=gridSize;
//定义列
int C=gridColSize[0];
//二维坐标转成一维索引,然后全部初始化;
int total=R*C;
//初始化parent
int parent[total];
for(int i=0;i<total;i++){
parent[i]=i;
}
//遍历所有结点,,如果有1则count加1,然后找左和下且为1的元素,如果满足是左和下且为1,
//按理说应该是同一个岛屿,
//如果两个元素的根节点不同(初始状态根节点不同),那么count减1,这个减去的1会在再次遍历到这个位置的时候再被加回来.
//如果两个元素根节点相同(说明已经被合并过了,即被连接过了,即减过那个1了),那么什么也不需要做.
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
if(grid[i][j]=='1'){
count++;
// grid[i][j]=0;
if(i+1<R&&grid[i + 1][j] == '1')
count-=union_vertices(i * C + j, (i+1) * C +j ,parent);
if(j + 1 < C && grid[i][j + 1] == '1')
count-=union_vertices(i * C + j, i * C + (j + 1),parent);
}
}
}
return count;
}
//找根节点
find_root(int x,int parent[]){
int x_root=x;
while(parent[x_root]!=x_root){
x_root=parent[x_root];
}
return x_root;;
}
//结点合并
int union_vertices(int x,int y, int parent[]){
int x_root=find_root(x,parent);
int y_root=find_root(y,parent);
if(x_root!=y_root)
{
parent[x_root]=y_root;
return 1;
}
return 0;
}
java解答方法同c语言
class Solution {
public int numIslands(char[][] grid) {
//cout统计岛屿数量
int count=0;
//定义行
int R=grid.length;
//定义列
int C=grid[0].length;
//二维坐标转成一维索引,然后全部初始化;
int total=R*C;
int [] parent=new int[total];
//pzrent数组初始化
for(int i=0;i<total;i++){
parent[i]=i;
}
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
if(grid[i][j]=='1'){
count++;
// grid[i][j]=0;
if(i+1<R&&grid[i + 1][j] == '1')
count-=union_vertices(i * C + j, (i+1) * C +j ,parent);
if(j + 1 < C && grid[i][j + 1] == '1')
count-=union_vertices(i * C + j, i * C + (j + 1),parent);
}
}
}
return count;
}
public int find_root(int x,int [] parent){
int x_root=x;
while(parent[x_root]!=x_root){
x_root=parent[x_root];
}
return x_root;
}
public int union_vertices(int x,int y,int []parent){
int x_root=find_root(x,parent);
int y_root=find_root(y,parent);
if(x_root!=y_root){
parent[x_root]=y_root;
return 1;
}
return 0;
}
}
总结:
二维数组转化为1维数组需要熟练运用,后来开始刷深度和广度,把这道题再搞一遍.然后注意联合时候返回的1,和0的道理.题目虽然解法很多,但是还要注意能节省空间就省,提高性能是改进算法必须的.(懒,没有设置树高,来提高性能,套路都是一样的)*