leetcode 684. 冗余连接 -Go语言实现

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])
}

猜你喜欢

转载自blog.csdn.net/weixin_45867397/article/details/121041872