题目描述
树可以看成是一个连通且 无环 的 无向 图。
给定往一棵 n 个节点 (节点值 1~n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n 的二维数组 edges ,edges[i] = [ai, bi] 表示图中在 ai 和 bi 之间存在一条边。
请找出一条可以删去的边,删除后可使得剩余部分是一个有着 n 个节点的树。如果有多个答案,则返回数组 edges 中最后出现的边。
解题思路
数据结构,算法
并查集,记录已经联通的点
思路
首先,题目要求我们删除一条边,那么对于一个环形,有可能会有多个解的情况,所以这时候我们要做的是删除最后一条边
找到一条可以删除的边
我们如果要确定一条边可以被删除,那么一定是这条边的两个节点已经被连接到了另一个 root 上,因此如果在并查集中,我们可以确定两个节点已经被链接,那么一定这条边可以作为我们的候选答案
过程
我们遍历 edges,对于每条边的两个点,我们看他们是否已经都被连接到了同一个 root 上,如果是的话,那么这是一个可选的答案,最终返回最后一个答案
代码
/**
* @param {number[][]} edges
* @return {number[]}
*/
var findRedundantConnection = function (edges) {
const n = edges.length
const u = new UnionSet(n)
let ret
for (const item of edges) {
const node1 = item[0]
const node2 = item[1]
if (u.get(node1) === u.get(node2)) {
ret = item
}
u.merge(node1, node2)
}
return ret
}
class UnionSet {
constructor(n) {
this.fa = []
for (let i = 0; i <= n; i++) {
this.fa[i] = i
}
}
get(x) {
return (this.fa[x] = this.fa[x] === x ? x : this.get(this.fa[x]))
}
merge(a, b) {
this.fa[this.get(b)] = this.get(a)
}
}