js(94)~[685] 冗余连接 II

117 阅读1分钟

力扣本题传送门 image.png

这道题,也是并查集,只不过,之前的并查集还要在改造一下,就是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