网络异常,图片无法展示
|
树可以看成是一个连通且 无环 的 无向 图。
给定往一棵 n
个节点 (节点值 1~n
) 的树中添加一条边后的图。添加的边的两个顶点包含在 1
到 n
中间,且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n
的二维数组 edges
,edges[i] = [ai, bi]
表示图中在 ai
和 bi
之间存在一条边。
请找出一条可以删去的边,删除后可使得剩余部分是一个有着 n
个节点的树。如果有多个答案,则返回数组 edges
中最后出现的边。
示例 1:
网络异常,图片无法展示
|
输入: edges = [[1,2], [1,3], [2,3]] 输出: [2,3] 复制代码
示例 2:
网络异常,图片无法展示
|
输入: edges = [[1,2], [2,3], [3,4], [1,4], [1,5]] 输出: [1,4] 复制代码
提示:
n == edges.length
3 <= n <= 1000
edges[i].length == 2
1 <= ai < bi <= edges.length
ai != bi
edges
中无重复元素- 给定的图是连通的
解题思路
本题要找出冗余的连接,即当前某个连接不连接,依然可以保证所有节点已经连通。
所以可以遍历输入数组,将两个节点合并到一个集合,如果遍历到某条边,当前两节点已经处于同一集合,则说明该边是一条可以删除的边。
那么在这个过程中我们需要获取元素所在集合,以及合并两个元素所在的集合。对于这种问题,可以使用并查集来解题。如果你对 并查集
还不了解,可以看我这一篇文章 数据结构-并查集,文中介绍了并查集的概念、应用场景以及手写实现的全过程。
代码实现
class UnionSet { constructor(n){ // 初始化节点数量数组 this.size = Array(n).fill(1); // 初始化集合列表,每一个节点为一个集合 this.list = Array(n) for(let i = 0;i<n;i++){ this.list[i] = i; } } // 递归获取元素所在集合根节点 find(x){ if(this.list[x]===x) return x; // 获取到元素所在集合根节点 const root = this.find(this.list[x]) // 将当前节点挂载为根节点子节点,压缩路径 this.list[x] = root; return root; } // 合并两个元素所在集合 merge(a,b){ // 获取两个元素所在集合的根节点 const rootA = this.find(a), rootB = this.find(b); // 如果两个根节点相同,则两元素处于同一集合,无需再合并 if(rootA===rootB) return; // 如果 a 所在集合元素数量更多,将 b 所在集合合并到 a 所在集合 if(this.size[rootA]>this.size[rootB]){ this.list[rootB] = rootA; this.size[rootA] += this.size[rootB] }else{ // 反之将 a 所在集合合并到 b 所在集合 this.list[rootA] = rootB; this.size[rootB] += this.size[rootA] } } } var findRedundantConnection = function(edges) { // 获取连接数量 const len = edges.length, // 创建并查集实例 unionset = new UnionSet(len+1); // 遍历连接 for(let i = 0;i<len;i++){ const [a,b] = edges[i] // 如果当前两个节点已经连接,则说明当前连接是冗余连接,返回当前连接 if(unionset.find(a)===unionset.find(b)) return [a,b] // 连接当前连接两个节点 unionset.merge(a,b) } }; 复制代码
至此我们就完成了 leetcode-684-冗余连接
如有任何问题或建议,欢迎留言讨论!