08数据结构与算法刷题之【并查集】篇

简介: 08数据结构与算法刷题之【并查集】篇

基础知识点


并查集(Union-find Data Structure)是一种树型的数据结构。它的特点是由子结点找到父亲结点,用于处理一些不交集(Disjoint Sets)的合并及查询问题。


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

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


剑指offer


剑指 Offer II 116. 省份数量【中等】


学习:leetcode/并查集/深度优先搜索/朋友圈问题/岛屿问题


题目链接:剑指 Offer II 116. 省份数量


题目内容:


有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。
省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。
给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。
返回矩阵中 省份 的数量。


思路:


1、并查集


复杂度分析:时间复杂度O(nm);空间复杂度O(n)


class Solution {
    public int findCircleNum(int[][] isConnected) {
        UnionFind uf = new UnionFind(isConnected);
        int len1 = isConnected.length;
        int len2 = isConnected[0].length;
        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < len2; j++) {
                if (isConnected[i][j] == 0) continue;
                uf.merge(i, j);
            }
        }
        return uf.size;
    }
}
class UnionFind {
    public int size;
    private int[] parent;
    private int[] weight;
    public UnionFind(int[][] isConnected) {
        int n = isConnected.length;
        this.size = n;
        this.parent = new int[n];
        this.weight = new int[n];
        for (int i = 0; i < n; i++) {
            this.parent[i] = i;
            this.weight[i] = 1;
        }
    }
    public int find(int x) {
        if (x == parent[x]) {
            return x;
        }else {
            parent[x] = find(parent[x]);
            return parent[x];
        }
    }
    public void merge(int x, int y) {
        int _x = find(x);
        int _y = find(y);
        if (_x == _y) return;
        if (weight[_x] < weight[_y]) {
            int temp = _x;
            _x = _y;
            _y = temp;
        }
        parent[_y] = parent[_x];
        weight[_x] += weight[_y];
        --size;
    }
}



leetcode


剑指 Offer II 105. 岛屿的最大面积【中等】


题目链接:剑指 Offer II 105. 岛屿的最大面积


题目内容;


思路:


1、dfs深搜


复杂度分析:时间复杂度O(mn);空间复杂度O(mn)


class Solution {
    private int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    private int max = 0;
    public int maxAreaOfIsland(int[][] grid) {
        //遍历一遍,若是为1进行dfs,然后res+1
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[i].length; j++) {
                if (grid[i][j] == 1) {
                    max = Math.max(dfs(grid, i, j, 1), max);
                }
            }
        }
        return max;
    }
    public int dfs(int[][] grid, int i, int j, int area) {
        //边界
        if (i < 0 || i >= grid.length || j < 0 || j >= grid[i].length) {
            return 0;
        }
        //若是为1的进行标注并继续往下执行
        if (grid[i][j] == 0) {
            return 0;
        }
        //地图位置进行标注
        grid[i][j] = 0;
        //四个方向进行执行
        int res = 1;
        for (int[] direction: directions) {
            res += dfs(grid, i + direction[0], j + direction[1], area + 1);
        }
        return res;
    }
}



2、并查集


复杂度分析:时间复杂度O(mn);空间复杂度O(mn)


class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        if (grid == null || grid.length == 0 || grid[0].length == 0) {
            return 0;
        }
        //初始化并查集
        UnionFind unionFind = new UnionFind(grid);
        int iLen = grid.length;
        int jLen = grid[0].length;
        //遍历一遍,若是为1进行dfs,然后res+1
        for (int i = 0; i < iLen; i++) {
            for (int j = 0; j < jLen; j++) {
                if (grid[i][j] == 0) continue;
                //四个方向
                if (i - 1 >= 0 && grid[i - 1][j] == 1) 
                    unionFind.merge(i * jLen + j, (i - 1) * jLen + j);
                if (i + 1 < iLen && grid[i + 1][j] == 1) 
                    unionFind.merge(i * jLen + j, (i + 1) * jLen + j);
                if (j - 1 >= 0 && grid[i][j - 1] == 1) 
                    unionFind.merge(i * jLen + j, i * jLen + j - 1);
                if (j + 1 < jLen && grid[i][j + 1] == 1) 
                    unionFind.merge(i * jLen + j, i * jLen + j + 1);
            }
        }
        int max = 0;
        for (int i = 0; i < iLen; i++) {
            for (int j = 0; j < jLen; j++) {
                max = Math.max(max, unionFind.weight[i * jLen + j]);
            }
        }
        return max;
    }
}
class UnionFind {
    public int size;
    public int[] parent;
    public int[] weight;
    public UnionFind(int[][] grid) {
        int len1 = grid.length;
        int len2 = grid[0].length;
        this.size = len1 * len2;
        this.parent = new int[size];
        this.weight = new int[size];
        //初始化
        for (int i = 0; i < len1; i++) {
            for (int j = 0; j < len2; j++) {
                parent[i * len2 + j] = i * len2 + j;
                //根据岛屿是否为1来设置权重是否为1
                if (grid[i][j] == 1) {
                    weight[i * len2 + j] = 1;
                }else {
                    weight[i * len2 + j] = 0;
                }
            }
        }
    }
    public int find(int x) {
        if (x == parent[x]) {
            return x;
        }else {
            parent[x] = find(parent[x]);
            return parent[x];
        }
    }
    public void merge(int x, int y) {
        int _x = find(x);
        int _y = find(y);
        if (_x == _y) return;
        if (weight[_x] < weight[_y]) {
            int temp = _x;
            _x = _y;
            _y = temp;
        }
        //连通结点
        parent[_y] = _x;
        weight[_x] += weight[_y];
        --size;
    }
}
相关文章
|
2天前
|
机器学习/深度学习 存储 算法
【算法沉淀】刷题笔记:并查集 带权并查集+实战讲解
【算法沉淀】刷题笔记:并查集 带权并查集+实战讲解
|
2天前
|
容器
数据结构:并查集
数据结构:并查集
27 0
数据结构:并查集
|
2天前
|
存储 算法 Java
【Java高阶数据结构】并查集-最小生成树(下)
【Java高阶数据结构】并查集-最小生成树
11 3
|
2天前
|
存储 算法 Java
【Java高阶数据结构】并查集-最小生成树(上)
【Java高阶数据结构】并查集-最小生成树(上)
11 2
|
1天前
|
机器学习/深度学习 存储
数据结构(九)---并查集
数据结构(九)---并查集
11 5
|
2天前
|
存储 算法 容器
算法刷题小技巧【持续补充~】
算法刷题小技巧【持续补充~】
9 2
|
2天前
|
算法 安全 定位技术
【刷题】备战蓝桥杯 — dfs 算法
dfs算法在数据较小的情况下可以使用。 一定一定要确定好终止条件,避免栈溢出。 相应做好回溯,保证每次的遍历都是不一样的选择,避免少结果。 针对题目进行对应细节处理,有能力的话可以进行剪枝优化!!!
14 0
|
2天前
|
算法 测试技术
并查集算法
并查集算法
|
2天前
|
算法
算法系列--链表刷题(二)(下)
算法系列--链表刷题(二)(下)
18 0
|
2天前
|
算法
算法系列--链表刷题(二)(上)
算法系列--链表刷题(二)
19 0