Union-Find
Union-Find
Union-Find 主要用于解决图的动态连通性问题
不管是quick-find,还是quick-union 都根据触电为索引的id数组来确定两个触点是否从存在相同的联通分量中。
- init初始化id数组
- find(x int) int
返回x所在树的root索引 - union(x, y int)
将x,y所在的树联通
quick-union 算法实现
var nums [1002]int
func findRedundantConnection(edges [][]int) []int {
initNums()
for i := 0; i < len(edges); i++ {
x := edges[i][0]
y := edges[i][1]
if find(x) == find(y) {
return edges[i]
} else {
union(x, y)
}
}
return nil
}
func initNums() {
for i := 1; i < len(nums); i++ {
nums[i] = i
}
}
func union(x, y int) {
tx := find(x)
ty := find(y)
nums[tx] = ty
}
func find(x int) int {
if nums[x] == x {
return x
}
return find(nums[x])
}
加权 quick-uinon 算法
quick-union 在极端情况下树的高度值会很大,而这个高度值就是find所要追溯的层数。
加权quick-union在union操作的时候,将权重小的树作为权重大的树的孩子, 从而保证树的高度不会太高
var ids []int
var ranks []int
func findRedundantConnection(edges [][]int) []int {
initIds(len(edges))
for i := 0; i < len(edges); i++ {
x := edges[i][0]
y := edges[i][1]
if find(x) == find(y) {
return edges[i]
} else {
union(x, y)
}
}
return nil
}
func initIds(size int) {
ids = make([]int, size+1)
ranks = make([]int, size+1)
for i := 1; i < len(ids); i++ {
ids[i] = i
ranks[i] = 1
}
}
func union(x, y int) {
i := find(x)
j := find(y)
if ranks[i] > ranks[j] {
ids[j] = i
ranks[i] += ranks[j]
} else {
ids[i] = j
ranks[j] += ranks[i]
}
}
func find(x int) int {
if ids[x] == x {
return x
}
return find(ids[x])
}