力扣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--;
            }
        }

    }
    
}
相关推荐
JSU_曾是此间年少3 分钟前
数据结构——线性表与链表
数据结构·c++·算法
sjsjs1110 分钟前
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
数据结构·leetcode
此生只爱蛋1 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法
咕咕吖1 小时前
对称二叉树(力扣101)
算法·leetcode·职场和发展
九圣残炎2 小时前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
lulu_gh_yu2 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
丫头,冲鸭!!!2 小时前
B树(B-Tree)和B+树(B+ Tree)
笔记·算法
Re.不晚3 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
为什么这亚子3 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
4 小时前
开源竞争-数据驱动成长-11/05-大专生的思考
人工智能·笔记·学习·算法·机器学习