并查集

目录

并查集三步走

并查集,开始的时候大家都是孤岛,根节点就是自己,然后我们不断地合并、修改指针,直到所有边都访问到。

  1. 数组初始化,每个节点的 parent 指针都指向自己。数组 roots 存放所有节点的祖先节点(根节点,路径压缩)【如果要求子集中元素数量,那么还要再创建一个 counts 数组,存储一份子集元素中的数量,需要在 union 中更新】。
  2. 根据所有相连的边,不断地进行查找、合并。
  3. 查找用递归、同时能修改查找路径上的所有节点的 parent 指针,合并前先调用查找然后看是否同一子图,是则合并失败,不是则直接将 parent 指针修改一下即可。

**有向图是否有环?**拓扑排序 DAG !

**无向图是否有环?**并查集!

关于求子集的个数、子集中元素的个数,可以试试把问题转化为图的问题,那么就可以转化为子图的数目、子图中元素数目,应用图的搜索、并查集等!

Java 代码

public class UFC {
  
  private int[] roots;
  
  public UFC(int n) {
    // 并查集用数组存parent
    roots = new int[n];
    // 开始时都是孤岛,根节点的parent都指向自己
    for (int i = 0; i < n; i++) {
      roots[i] = i;
    }
  }
  
  // find 查找是递归
  public int findRoot(int i) {
    // 根节点一定指向自己
    if (roots[i] == i) return i;
    roots[i] = findRoot(roots[i]);
    return roots[i];
  }
  
  // union 合并改指针
  public boolean union(int i, int j) {
    int rootI = findRoot(i);
    int rootJ = findRoot(j);
    if (rootI == rootJ) return false;
    // 把根节点的parent指针直接更改
    roots[rootI] = rootJ; 
    return true;
  }
}
comments powered by Disqus

相关文章

MacBook 上安装 ArchLinux 双系统

动机 ¶ 希望将闲置的 2018 款 MBP 利用起来,整成一台 Linux 服务器就好了,因为 macOS 上的 Docker 非常难用,再加上我比较爱折腾,于是有了这个想法。 主要参考这个 wiki:https://wiki.t2linux.org Tip

阅读更多
JWT 的应用场景思考

JWT 的应用场景思考 ¶ 简述 JWT ¶ JWT,全称 JSON Web Token。是一种开放标准,用于在各方之间安全传递信息,它是以 Base64 编码 json 对象的 token 。基于 token 的权限验证,与传统的 Session 认证完全不同,它不需要服务端保持 Session 记录,连用户状态都不需要关心。一旦用户登录网站,服务器就会生成 token,之后客户端每次登录时在HTTP的头信息中带上 token 即可。

阅读更多
GORM 自动填充 UUID 的 2 种方式

使用 uuid 库手动生成 ¶ 采用这个库:github.com/gofrs/uuid 在 GORM 中定义一个 BaseModel,并增加钩子函数: import "github.com/gofrs/uuid" type BaseModel struct { ID uuid.UUID CreatedAt time.Time UpdatedAt time.Time DeletedAt gorm.DeletedAt `gorm:"index"` EffectiveTime *time.Time } func (m *BaseModel) BeforeCreate() (err error) { m.ID, err = uuid.NewV4() if err != nil { log.Logger.Err(err).Msg("uuid create failed") return fmt.Errorf("uuid create with ID failed, %w", err) } return nil } 使用 postgresql 的 uuid-ossp 插件 ¶ 首先要启用插件 要么手动 Navicat 界面上增加: 要么执行查询语句:

阅读更多