并查集 leetcode 200 岛屿数量

题目内容

给你一个由 ‘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的道理.题目虽然解法很多,但是还要注意能节省空间就省,提高性能是改进算法必须的.(懒,没有设置树高,来提高性能,套路都是一样的)*

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值