mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-04 16:12:47 +08:00
135 lines
2.5 KiB
Go
135 lines
2.5 KiB
Go
package template
|
|
|
|
// UnionFind defind
|
|
// 路径压缩 + 秩优化
|
|
type UnionFind struct {
|
|
parent, rank []int
|
|
count int
|
|
}
|
|
|
|
// Init define
|
|
func (uf *UnionFind) Init(n int) {
|
|
uf.count = n
|
|
uf.parent = make([]int, n)
|
|
uf.rank = make([]int, n)
|
|
for i := range uf.parent {
|
|
uf.parent[i] = i
|
|
}
|
|
}
|
|
|
|
// Find define
|
|
func (uf *UnionFind) Find(p int) int {
|
|
root := p
|
|
for root != uf.parent[root] {
|
|
root = uf.parent[root]
|
|
}
|
|
// compress path
|
|
for p != uf.parent[p] {
|
|
tmp := uf.parent[p]
|
|
uf.parent[p] = root
|
|
p = tmp
|
|
}
|
|
return root
|
|
}
|
|
|
|
// Union define
|
|
func (uf *UnionFind) Union(p, q int) {
|
|
proot := uf.Find(p)
|
|
qroot := uf.Find(q)
|
|
if proot == qroot {
|
|
return
|
|
}
|
|
if uf.rank[qroot] > uf.rank[proot] {
|
|
uf.parent[proot] = qroot
|
|
} else {
|
|
uf.parent[qroot] = proot
|
|
if uf.rank[proot] == uf.rank[qroot] {
|
|
uf.rank[proot]++
|
|
}
|
|
}
|
|
uf.count--
|
|
}
|
|
|
|
// TotalCount define
|
|
func (uf *UnionFind) TotalCount() int {
|
|
return uf.count
|
|
}
|
|
|
|
// UnionFindCount define
|
|
// 计算每个集合中元素的个数 + 最大集合元素个数
|
|
type UnionFindCount struct {
|
|
parent, count []int
|
|
maxUnionCount int
|
|
}
|
|
|
|
// Init define
|
|
func (uf *UnionFindCount) Init(n int) {
|
|
uf.parent = make([]int, n)
|
|
uf.count = make([]int, n)
|
|
for i := range uf.parent {
|
|
uf.parent[i] = i
|
|
uf.count[i] = 1
|
|
}
|
|
}
|
|
|
|
// Find define
|
|
func (uf *UnionFindCount) Find(p int) int {
|
|
root := p
|
|
for root != uf.parent[root] {
|
|
root = uf.parent[root]
|
|
}
|
|
return root
|
|
}
|
|
|
|
// 不进行秩压缩,时间复杂度爆炸,太高了
|
|
// func (uf *UnionFindCount) union(p, q int) {
|
|
// proot := uf.find(p)
|
|
// qroot := uf.find(q)
|
|
// if proot == qroot {
|
|
// return
|
|
// }
|
|
// if proot != qroot {
|
|
// uf.parent[proot] = qroot
|
|
// uf.count[qroot] += uf.count[proot]
|
|
// }
|
|
// }
|
|
|
|
// Union define
|
|
func (uf *UnionFindCount) Union(p, q int) {
|
|
proot := uf.Find(p)
|
|
qroot := uf.Find(q)
|
|
if proot == qroot {
|
|
return
|
|
}
|
|
if proot == len(uf.parent)-1 {
|
|
//proot is root
|
|
} else if qroot == len(uf.parent)-1 {
|
|
// qroot is root, always attach to root
|
|
proot, qroot = qroot, proot
|
|
} else if uf.count[qroot] > uf.count[proot] {
|
|
proot, qroot = qroot, proot
|
|
}
|
|
|
|
//set relation[0] as parent
|
|
uf.maxUnionCount = max(uf.maxUnionCount, (uf.count[proot] + uf.count[qroot]))
|
|
uf.parent[qroot] = proot
|
|
uf.count[proot] += uf.count[qroot]
|
|
}
|
|
|
|
// Count define
|
|
func (uf *UnionFindCount) Count() []int {
|
|
return uf.count
|
|
}
|
|
|
|
// MaxUnionCount define
|
|
func (uf *UnionFindCount) MaxUnionCount() int {
|
|
return uf.maxUnionCount
|
|
}
|
|
|
|
func max(a int, b int) int {
|
|
if a > b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|