|
| 1 | +/** |
| 2 | + * 685. Redundant Connection II |
| 3 | + * https://leetcode.com/problems/redundant-connection-ii/ |
| 4 | + * Difficulty: Hard |
| 5 | + * |
| 6 | + * In this problem, a rooted tree is a directed graph such that, there is exactly one node |
| 7 | + * (the root) for which all other nodes are descendants of this node, plus every node has |
| 8 | + * exactly one parent, except for the root node which has no parents. |
| 9 | + * |
| 10 | + * The given input is a directed graph that started as a rooted tree with n nodes (with |
| 11 | + * distinct values from 1 to n), with one additional directed edge added. The added edge |
| 12 | + * has two different vertices chosen from 1 to n, and was not an edge that already existed. |
| 13 | + * |
| 14 | + * The resulting graph is given as a 2D-array of edges. Each element of edges is a pair |
| 15 | + * [ui, vi] that represents a directed edge connecting nodes ui and vi, where ui is a parent |
| 16 | + * of child vi. |
| 17 | + * |
| 18 | + * Return an edge that can be removed so that the resulting graph is a rooted tree of n |
| 19 | + * nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array. |
| 20 | + */ |
| 21 | + |
| 22 | +/** |
| 23 | + * @param {number[][]} edges |
| 24 | + * @return {number[]} |
| 25 | + */ |
| 26 | +var findRedundantDirectedConnection = function(edges) { |
| 27 | + const n = edges.length; |
| 28 | + const parent = Array.from({ length: n + 1 }, (_, i) => i); |
| 29 | + const rank = new Uint32Array(n + 1); |
| 30 | + const parents = new Int32Array(n + 1).fill(-1); |
| 31 | + let conflict = -1; |
| 32 | + let cycle = -1; |
| 33 | + |
| 34 | + edges.forEach(([u, v], i) => { |
| 35 | + if (parents[v] !== -1) conflict = i; |
| 36 | + else { |
| 37 | + parents[v] = u; |
| 38 | + union(u, v) || (cycle = i); |
| 39 | + } |
| 40 | + }); |
| 41 | + |
| 42 | + return conflict === -1 ? edges[cycle] : cycle === -1 |
| 43 | + ? edges[conflict] : [parents[edges[conflict][1]], edges[conflict][1]]; |
| 44 | + |
| 45 | + function find(x) { |
| 46 | + return parent[x] === x ? x : (parent[x] = find(parent[x])); |
| 47 | + } |
| 48 | + function union(x, y) { |
| 49 | + const [px, py] = [find(x), find(y)]; |
| 50 | + if (px === py) return false; |
| 51 | + rank[px] < rank[py] |
| 52 | + ? parent[px] = py |
| 53 | + : rank[px] > rank[py] ? parent[py] = px : (parent[py] = px, rank[px]++); |
| 54 | + return true; |
| 55 | + } |
| 56 | +}; |
0 commit comments