前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >200. 岛屿的个数

200. 岛屿的个数

作者头像
张伦聪zhangluncong
发布2022-10-26 18:29:20
1570
发布2022-10-26 18:29:20
举报

给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。

示例 1:

输入:
11110
11010
11000
00000

输出: 1

示例 2:

输入:
11000
11000
00100
00011

输出: 3

解:这题直接用并查集也比较简单。

class Solution {
    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
        int row = grid.length;
        int col = grid[0].length;
        UnionFind uf = new UnionFind();
        uf.init(row * col);
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == '1') {
                    //上
                    if ((i - 1) >= 0 && grid[i - 1][j] == '1') {
                        uf.union(node(col, i, j), node(col, i - 1, j));
                    }
                    //下
                    if ((i + 1) < row && grid[i + 1][j] == '1') {
                        uf.union(node(col, i, j), node(col, i + 1, j));
                    }
                    //左
                    if ((j - 1) >= 0 && grid[i][j - 1] == '1') {
                        uf.union(node(col, i, j), node(col, i, j - 1));
                    }
                    //右
                    if ((j + 1) < col && grid[i][j + 1] == '1') {
                        uf.union(node(col, i, j), node(col, i, j + 1));
                    }
                }
            }
        }

        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == '1') {
                    set.add(uf.getRoot(node(col, i, j)));
                }
            }
        }
        return set.size();
    }

    private int node(int col, int i, int j) {
        return i * col + j;
    }
}

public class UnionFind {
    //pre[i]保存的是i的上级
    private int[] pre;

    //初始化,每个人的上级就是他自己,自成一派,形成了n个独立的集合
    public void init(int n) {
        this.pre = new int[n];
        for (int i = 0; i < n; i++) {
            pre[i] = i;
        }
    }

    //合并p,q两个对象所在集合
    public void union(int p, int q) {
        int rootP = getRoot(p);
        int rootQ = getRoot(q);
        //任意赋值,也可以pre[rootP] = rootQ;
        //只要能并起来就行
        pre[rootQ] = rootP;
    }

    //在p所在集合中查找q是否归属于这个集合
    public boolean find(int p, int q) {
        int rootP = getRoot(p);
        int rootQ = getRoot(q);
        return rootP == rootQ;
    }

    //查找i的最顶级上级
    //随着集合构造的树高度越高,时间复杂度会变得越高
    //所以我们可以进行优化,每次进行查找根的时候,
    //直接上级直接改成根节点,这样树就变得更加扁平
    //提升查找速度
    public int getRoot(int i) {
        int tmp = i;
        while (tmp != pre[tmp]) {
            tmp = pre[tmp];
        }
        pre[i] = tmp;
        return tmp;
    }

    public static void main(String[] args) {
        UnionFind unionFind = new UnionFind();
        //初始化10个独立集合
        unionFind.init(10);
        //将1所在集合,2所在集合组成一个集合,结果1,2
        unionFind.union(1, 2);
        //将3所在集合,4所在集合组成一个集合,结果3,4
        unionFind.union(3, 4);
        //将1所在集合,3所在集合组成一个集合,结果1,2,3,4
        unionFind.union(1, 3);
        //将5所在集合,6所在集合组成一个集合,结果5,6
        unionFind.union(5, 6);
        unionFind.find(4, 6);
        unionFind.find(2, 4);
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-09-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档