首页 > 编程语言 >【唐叔学算法】第八天:并查集-图论连通性的大杀器

【唐叔学算法】第八天:并查集-图论连通性的大杀器

时间:2024-12-08 23:29:20浏览次数:6  
标签:连通性 parent int 唐叔学 杀器 查集 合并 rank 算法

你是否曾为如何高效地解决图论中的连通性问题而烦恼?并查集算法,就像一张无形的网,能帮你轻松连接所有节点。今天,就让我们一起揭开并查集算法的神秘面纱,探索它在Java编程中的应用。

并查集是什么?

并查集(Union-Find)是一种数据结构,用于处理一些不交集的合并及查询问题。它支持两种操作:

  • 合并(Union):将两个集合合并为一个集合。
  • 查询(Find):查询某个元素所属的集合。

并查集算法通常采用树形结构表示,每个节点包含一个指向父节点的指针。通过不断向上回溯,可以找到该节点所属的集合的代表元素。

并查集的应用场景

并查集算法广泛应用于以下场景:

  • 动态连通性问题:处理动态加入或删除边的情况。
  • 网络流问题:判断两个节点是否在同一个网络流中。
  • 图的连通性检测:判断两个顶点是否在同一个连通分量内。
  • 社交网络分析:判断两个用户是否属于同一个社交圈。
  • 等价类划分:将具有相同属性的元素划分到同一个集合中。

并查集的使用

使用并查集算法的关键在于:

  1. 初始化:创建一个并查集,并为每个元素设置一个父节点,指向自身。
  2. 查询(Find):使用路径压缩技术,将查询路径上的所有节点都指向代表元素,从而提高查询效率。
  3. 合并(Union):使用按秩合并技术,将两个集合合并为一个集合,并保持树的高度最小。

说明:

  • 路径压缩:在查找过程中,将查找路径上的所有节点直接指向根节点,以加速后续查找。
  • 按秩合并:在合并时,优先将较小的树合并到较大的树上,以保持树的平衡。

注意事项

在使用并查集算法时,需要注意以下几点:

  • 初始化:确保每个元素的初始状态正确,避免后续操作出错。
  • 路径压缩:可以显著提高查询效率,但会增加合并操作的复杂度。
  • 按秩合并:可以保持树的高度最小,从而提高查询和合并的效率。
  • 时间复杂度:并查集算法的查询和合并操作的平均时间复杂度通常为 O(α(n)),其中 α(n) 是阿克曼函数的反函数,增长非常缓慢。

LeetCode实战

入门题目 - 200. 岛屿数量

题目描述: 给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

解题思路

将每个岛屿视为一个集合,通过并查集算法判断两个陆地单元格是否属于同一个岛屿。遍历所有单元格,如果是陆地,则将其与周围陆地单元格进行合并。

Java代码实现
public class Solution {
    public int numIslands(char[][] grid) {
        int m = grid.length, n = grid[0].length;
        UnionFind uf = new UnionFind(m * n);
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (grid[i][j] == '1') {
                    int idx = i * n + j;
                    if (i > 0 && grid[i - 1][j] == '1') {
                        uf.union(idx, (i - 1) * n + j);
                    }
                    if (j > 0 && grid[i][j - 1] == '1') {
                        uf.union(idx, i * n + (j - 1));
                    }
                }
            }
        }
        return uf.getCount();
    }
}

/**
 * 并查集类
 */
class UnionFind {
    private int[] parent;
    private int[] rank;
    private int count;

    public UnionFind(int size) {
        parent = new int[size];
        rank = new int[size];
        count = size;
        for (int i = 0; i < size; i++) {
            parent[i] = i;
            rank[i] = 0;
        }
    }

    public int find(int x) {
        if (parent[x] != x) {
            parent[x] = find(parent[x]);
        }
        return parent[x];
    }

    public void union(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX != rootY) {
            if (rank[rootX] < rank[rootY]) {
                parent[rootX] = rootY;
            } else if (rank[rootX] > rank[rootY]) {
                parent[rootY] = rootX;
            } else {
                parent[rootY] = rootX;
                rank[rootX]++;
            }
            count--;
        }
    }

    public int getCount() {
        return count;
    }
}

中等难度题目 - 547. 省份数量

题目描述: 有 n 个城市和一些双向连接这些城市的道路。每个城市与相邻城市直接相连,共计有 m 条道路。返回城市的省份数量。

解题思路

与岛屿数量类似,将每个城市视为一个集合,通过并查集算法判断两个城市是否属于同一个省份。遍历所有道路,将相邻城市进行合并。

Java代码实现
public int findCircleNum(int[][] isConnected) {
    int n = isConnected.length;
    UnionFind uf = new UnionFind(n);
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (isConnected[i][j] == 1) {
                uf.union(i, j);
            }
        }
    }
    return uf.getCount();
}

更多LeetCode题目推荐

如果您对并查集算法感兴趣,希望挑战更多题目,以下是一些LeetCode上推荐的题目:

结语

并查集算法就像一张无形的网,能帮你轻松连接所有节点。希望本文能让你对并查集算法有更深入的理解,并在实际编程中灵活运用。


如果喜欢这篇文章,别忘了点赞和分享哦!

标签:连通性,parent,int,唐叔学,杀器,查集,合并,rank,算法
From: https://blog.csdn.net/Tang_is_learning/article/details/144334564

相关文章

  • 重链剖分, 树上路径问题大杀器
    重链剖分,树上路径问题大杀器首先,什么是树链剖分数组,要进行修改查询是非常方便的,一眼线段树.但是树并不是.看一下我们目前已有的树上修改查询技术.树上差分只能修改,最后才能查询,不然就只能很慢的单点查询,DFS序+线段树只能进行子树操作,不能进行路径操作.......
  • 【唐叔学算法】第一天:Java常见数据结构
    工欲善其事必先利其器。虽然算法本身是不区分语言的,但是作为专注于Java开发的唐叔,那么善于使用Java自带的已实现的数据结构,将有利于在更短的时间内快速通关具体的算法题。而今天我们就来学习Java中的数据结构实现。善用这些API将有助于我们更有效地存储和处理数据。数组(Ar......
  • 【唐叔学算法】第二天:探索递归的魅力
    递归算法简介递归算法是一种在解决问题时,将问题分解成更小的、相似的子问题来解决的方法。它是一种非常强大的编程技术,尤其适用于那些可以自然分解为相似子问题的场景。递归算法的核心思想是:问题可以分解为更小的相同问题,直到问题足够小以至于可以直接解决。如何使用递归......
  • 运维脚本:网络连通性测试
    1. 背景介绍在日常运维工作中,网络连通性是确保系统稳定性和高可用性的关键因素之一。通过测试网络连通性,运维人员可以快速诊断网络问题,判断系统与其他设备或服务的连接状态。这对于预防和处理网络故障至关重要。本文将介绍如何编写和使用一个简单的运维脚本,来自动化测试服务器......
  • Linux下端口连通性测试
    端口连通性测试使用nc命令Linux下自带/dev/tcp命令#!/bin/bash#检测脚本传入的参数if[$#-eq0];thenecho"使用格式:$0<IPPORT>|-f<file>"echo"<IPPORT>测试单个IP和端口"echo"-f<file>批量测试,使用参数-f指定要测试......
  • 图的连通性小记
    前言DFS树无向图DFS树定义:DFS树是在图或树结构上进行深度优先搜索时形成的树。在DFS过程中,从一个顶点开始,尽可能深地搜索图的分支,直到达到一个没有未访问邻居的顶点,然后回溯到上一个顶点继续搜索。从点\(r\)开始搜索,每次进入一个点\(i\)对应的边\((fa_i,i)\)为树......
  • Serverless 安全新杀器:云安全中心护航容器安全
    作者:胡志广(独鳌)云安全中心对于Serverless容器用户的价值从云计算发展之初,各大云厂商及传统安全厂商就开始围绕云计算的形态来做安全解决方案。传统安全与云计算安全的形态与做法开始发生变化,同时随着这10多年的发展,安全越来越被国家、企业重视,安全本身也在不断的发生变化......
  • WGCLOUD使用指南 - 监测数据库的连通性
    数据可视化监测是WGCLOUD的一个重要模块,可以帮我们监控数据源是否在线,自定义sql查询数据进行可视化展示,比如新增订单、注册用户量、数据库运行参数等信息数据监控是由server来监测的,因此要保证server主机能够访问到数据库如果server无法访问被监控的数据源,怎么监控 1、......
  • 图论连通性相关
    并查集普通并查集:路径压缩写法:structUnion_Find_Set{ intf[N]; inlinevoidinit(){ for(inti=1;i<=n;++i) f[i]=i; } inlineintfind(intx){ if(x!=f[x])f[x]=find(f[x]); returnf[x]; } inlinevoidmerge(inta,intb){ intx......
  • 使用python做页面,测试数据库连通性!免费分享!测试通过~
    免费分享刚刚写的一个小程序,测试通过没问题,解BUG也就花了半小时吧有更好的方法欢迎评论区推给我谢谢。importtkinterastkfromtkinterimportmessageboximportpymysqldefget_db_info(db_source):ifdb_source=='database1':hostname=e1.get()......