码迷,mamicode.com
首页 > 其他好文 > 详细

【40讲系列14】并查集

时间:2020-12-04 11:19:39      阅读:6      评论:0      收藏:0      [点我收藏+]

标签:路径压缩   nio   连通块   创建   bfs   内存   nbsp   isl   考题   

一、理论

并查集的定义:

并查集是一种树型的数据结构,用于处理一些不交集的合并和查询问题。一般用数组实现。

Find:确定元素属于哪一个子集,它可以被用来确定两个元素是否属于同一个子集。

Union:将两个子集合并成同一个集合。

并查集的优化:

优化1: 降低rank,提高查询效率。合并时要考虑rank(即树结构的深度,在并查集里称为rank),优先让rank低的合并到rank高的。

优化2:路径压缩。不需要创建额外的内存,rank。 用的更多。

二、典型例题

☆☆①:二维网格中的小岛数量统计问题(LC200)

Note:【岛屿问题】是一个系列的网格问题,LC463->岛屿的周长、 LC695->岛屿的最大面积 、LC827->最大人工岛

此类问题参考题解:岛屿类问题的通用解法、DFS 遍历框架

方法1:DFS。一般DFS通常是在树或图结构上进行的,岛屿系列问题是网格DFS的典型代表。

方法2:BFS

方法3:并查集

代码1<DFS>

class Solution {
    public int numIslands(char[][] grid) {
        int count = 0;
        if (grid == null || grid.length == 0) return count;
        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 r, int c) {
        // 超出网格范围。 "先污染后治理"->先往四个方向走一步再说,如果发现走出了网格范围再赶紧返回。
        if (r < 0 || r >= grid.length || c < 0 || c >= grid[0].length) {
            return;
        }
        // 如果这个格子不是岛屿,返回。有两种情况:‘0‘海洋格子。‘2‘陆地格子(已遍历过)
        if (grid[r][c] != ‘1‘) {
            return;
        }
        grid[r][c] = ‘2‘; // 避免重复遍历"兜圈子",标记已遍历过的格子
        dfs(grid,r-1,c);
        dfs(grid,r+1,c);
        dfs(grid,r,c-1);
        dfs(grid,r,c+1);
    }
}

 

②:计算矩阵中的朋友圈总数(LC547)

方法1:图的DFS。给定的矩阵看成图的邻接矩阵,问题可以变成求无向图连通块的个数。

方法2:图的BFS

方法3:并查集

代码1<DFS>

class Solution {
    public int findCircleNum(int[][] M) {
        /**
         * 方法1:图的DFS
         * 首先选择一个节点,访问任一相邻的节点。然后再访问这一节点的任一相邻节点。
         * 这样不断遍历到没有未访问的相邻节点时,回溯到之前的节点进行访问。
         */
        int count = 0;
        if (M == null || M.length == 0) return count;
        boolean[] visited = new boolean[M.length];
        for (int i = 0; i < M.length; i++) {
            if (!visited[i]) {
                dfs(M, visited, i);
                count++;
            }
        }
        return count;
    }
    public void dfs(int[][] M, boolean[] visited, int i) {
        visited[i] = true;
        for (int j = 0; j < M.length; j++) {
            if (!visited[j] && M[i][j] == 1) {
                dfs(M,visited,j);
            }
        }
    }
}

 代码3<并查集>

M

 

【40讲系列14】并查集

标签:路径压缩   nio   连通块   创建   bfs   内存   nbsp   isl   考题   

原文地址:https://www.cnblogs.com/HuangYJ/p/14057889.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!