这道题,也是并查集,只不过,之前的并查集还要在改造一下,就是unite这个方法判断少了一些,也不用size getCount这两个属性了
let root1 = this.find(index1), root2 = this.find(index2)
if (root1 < root2) {
[root1, root2] = [root2, root1]
}
this.parent[root2] = root1;
this.size[root1] += this.size[root2];
this.count--;
改造后
unite(index1, index2) {
let root1 = this.find(index1), root2 = this.find(index2)
this.parent[root2] = root1;
}
/*
* @lc app=leetcode.cn id=685 lang=javascript
*
*
*/
// @lc code=start
/**
* @param {number[][]} edges
* @return {number[]}
*/
// 无环 但是又2个入读点
class UnionFind {
constructor(n) {
// this.parent = new Array(n).fill(0).map((v, i) => i);
this.parent = [];
for (let i = 0; i < n; i++) {
this.parent[i] = i;
}
}
find(index) {
let root = this.parent[index];
if (root != index) {
root = this.find(root)
}
return root
}
unite(index1, index2) {
let root1 = this.find(index1), root2 = this.find(index2)
this.parent[root2] = root1;
}
getCount() {
return this.count;
}
}
var findRedundantDirectedConnection = function (edges) {
// 获取节点的个数 也就是边的个数
let nodeCount = edges.length;
// 根据节点数量 构建并查集 从长度+1开始 避免从0开始
let uf = new UnionFind(nodeCount + 1);
// 记录每一个父节点 是多少
let parent = [];
// 初始化
for (let i = 1; i < nodeCount + 1; i++) {
parent[i] = i;
}
// 记录是否存在双重父节点
let conflit = -1;
// 产生了环路
let cycle = -1;
for (const i in edges) {
let edge = edges[i];
let node1 = edge[0], node2 = edge[1];
// node2 有两个父节点
if (parent[node2] !== node2) {
conflit = i;
// 下面这个单词写错 让我好找
// confilt = i;
} else {
// if (parent[node2] !== node2) {
// // 记录下这是第几组数据
// confilt = i
// } else {
// 没有双重父节点 就连接起来
parent[node2] = node1;
// 出现环路
if (uf.find(node1) === uf.find(node2)) {
cycle = i;
} else {
// 基友环路 又有双重父节点
uf.unite(node1, node2)
}
}
}
// 没有双重父节点产生 就记录环路
if (conflit < 0) {
return edges[cycle]
} else {
// 只有一双重父节点
let confiltEdge = edges[conflit];
// 判断是否有环路
if (cycle >= 0) {
// 有两个入读点
return [parent[confiltEdge[1]], confiltEdge[1]]
} else {
return confiltEdge
}
}
};
// @lc code=end