力扣200岛屿数量解法3种

DFS BFS 并查集 三种方式解决岛屿问题

java 复制代码
import java.util.*;
public class Edit {
    //并查集版本
    public int numIslandsUnion(char[][] grid) {
        UnionSet unionfind = new UnionSet(grid);
        //unionfind.UnionSet(grid);
        for(int clow=1;clow<unionfind.clow;clow++){
            if(grid[0][clow-1]=='1'&&grid[0][clow]=='1'){
                unionfind.union(0,clow,0,clow-1);
            }
        }
        for(int row=1;row<unionfind.row;row++){
            if(grid[row-1][0]=='1'&&grid[row][0]=='1'){
                unionfind.union(row,0,row-1,0);
            }
        }
        for(int row=1;row<unionfind.row;row++){
            for(int clow=1;clow<unionfind.clow;clow++){
                if(grid[row][clow-1]=='1'&&grid[row][clow]=='1'){
                    unionfind.union(row,clow,row,clow-1);
                }
                if(grid[row-1][clow]=='1'&&grid[row][clow]=='1'){
                    unionfind.union(row,clow,row-1,clow);
                }
            }
        }
        return unionfind.sets;
    }



    //bfs版本
    public int numIslandsBfs(char[][] grid) {
        Queue<int[]> que = new LinkedList<int[]>();
        int count=0;
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[0].length;j++){
                if(grid[i][j]=='1'){
                    que.add(new int[]{i,j});
                    while(!que.isEmpty()){
                        int[] cur = que.poll();
                        int tempi= cur[0];
                        int tempj= cur[1];
                        if(tempi>=0&&tempj>=0&&tempj<grid[0].length&&tempi<grid.length&&grid[tempi][tempj]=='1'){
                            grid[tempi][tempj]='0';
                            que.add(new int[]{tempi+1,tempj});
                            que.add(new int[]{tempi-1,tempj});
                            que.add(new int[]{tempi,tempj+1});
                            que.add(new int[]{tempi,tempj-1});
                        }
                    }
                    count++;
                }

            }
        }
        return count;
    }

    //dfs版本
    public int numIslandsdfs(char[][] grid) {
        int count=0;
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[0].length;j++){
                if(grid[i][j]=='1'){
                    dfs(grid,i,j);
                    count++;
                }

            }
        }
        return count;
    }
    public void dfs(char[][] grid,int i,int j){
        if(i<0||j>=grid[0].length||i>=grid.length||j<0||grid[i][j]=='0'||grid[i][j]=='2'){
            return;
        }
        grid[i][j]='2';
        dfs(grid,i+1,j);
        dfs(grid,i-1,j);
        dfs(grid,i,j+1);
        dfs(grid,i,j-1);
        return;
    }
    //并查集方法
    public static class UnionSet{
        private int[] parents;//存父节点
        private int[] size;//存的大小
        private int[] help;//辅助数组,当作栈
        private int  clow;
        private int  row;
        private int  sets;

        //先初始化,values传入进来的数组
        public  UnionSet(char[][] values){
            sets=0;
            row = values.length;
            clow = values[0].length;
            int length = clow*row;
            parents = new int[length];//每个元素的负类
            size = new int[length];
            help = new int[length];
            for(int i=0;i<row;i++){
                for(int j=0;j<clow;j++){
                    int in =index(i,j);
                    if(values[i][j]=='1'){
                        parents[in]=in;
                        size[in]=1;
                        sets++;
                    }
                }
            }

        }
        public  int index(int x,int y){
            return x*clow+y;
        }
        //找寻当前节点的最上面的节点
        public int findHead(int cur){
            int index=0;
            //路径压缩,利用help数组存储,从当前节点cur访问到顶部节点所经过的节点
            //最后将所储存的节点的父节点全部设置为顶部节点,利用顶部节点来代表这个集合
            while(cur!=parents[cur]){
                help[index++]=cur;
                cur=parents[cur];
            }
            for (index--;index==0;index--){
                parents[help[index]]=cur;
            }
            return cur;
        }
        //判断是否是同一个集合
        public boolean isSameSet(int a,int b){
            //从a和b分别开始找顶部节点,若节点相同则认为在同一个集合,若不同则不在同一个集合
            return findHead(a)==findHead(b)?true:false;
        }
        //将a和b放入到一个集合当中
        public void union(int row1,int clow1 ,int row2,int clow2){
            int a = index(row1,clow1);
            int b = index(row2,clow2);
            int aHead=findHead(a);
            int bHead=findHead(b);
            if(aHead!=bHead){
                //将规模较小的集合插入大集合当中
                int asize = size[aHead];
                int bsize= size[bHead];
                int big= asize>=bsize?aHead:bHead;
                int small= asize<bsize?aHead:bHead;
                parents[small]=big;
                size[big]=asize+bsize;
                size[small]=0;
                sets--;
            }
        }

    }
    
}
相关推荐
仙俊红1 小时前
LeetCode487周赛T2,删除子数组后的最终元素
数据结构·算法
-dzk-7 小时前
【代码随想录】LC 59.螺旋矩阵 II
c++·线性代数·算法·矩阵·模拟
风筝在晴天搁浅8 小时前
hot100 78.子集
java·算法
Jasmine_llq8 小时前
《P4587 [FJOI2016] 神秘数》
算法·倍增思想·稀疏表(st 表)·前缀和数组(解决静态区间和查询·st表核心实现高效预处理和查询·预处理优化(提前计算所需信息·快速io提升大规模数据读写效率
超级大只老咪8 小时前
快速进制转换
笔记·算法
m0_706653238 小时前
C++编译期数组操作
开发语言·c++·算法
故事和你918 小时前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
qq_423233909 小时前
C++与Python混合编程实战
开发语言·c++·算法
TracyCoder1239 小时前
LeetCode Hot100(19/100)——206. 反转链表
算法·leetcode
m0_715575349 小时前
分布式任务调度系统
开发语言·c++·算法