1+ /**
2+ * @param {number[][] } edges
3+ * @return {number[] }
4+ */
5+ var findRedundantDirectedConnection = function ( edges ) {
6+ let inDegrees = createInDegrees ( edges )
7+ let edgesObj = createGraph ( edges )
8+ let states = createStates ( edges )
9+
10+ for ( let i = edges . length - 1 ; i >= 0 ; i -- ) {
11+ let notTree = false
12+ let [ srcKey , destKey ] = edges [ i ]
13+ removeEdge ( edgesObj , srcKey , destKey , inDegrees )
14+ // detect valid tree structure
15+ for ( let start = 1 ; start <= edges . length ; start ++ ) {
16+ if ( hasCycle ( start , edgesObj , states ) || hasMultipleParents ( inDegrees ) ) {
17+ notTree = true
18+ states = createStates ( edges )
19+ addEdge ( edgesObj , srcKey , destKey , inDegrees )
20+ break
21+ }
22+ }
23+ if ( notTree ) continue
24+ return [ srcKey , destKey ]
25+ }
26+ } ;
27+
28+ function hasCycle ( start , edgesObj , states ) {
29+ if ( states [ start ] === - 1 ) return false
30+ if ( states [ start ] === 1 ) return true
31+ states [ start ] = 1
32+ if ( start in edgesObj ) {
33+ for ( let destKey of edgesObj [ start ] ) {
34+ if ( hasCycle ( destKey , edgesObj , states ) ) return true
35+ }
36+ }
37+ states [ start ] = - 1
38+ return false
39+ }
40+
41+ function createStates ( edges ) {
42+ const states = { }
43+ for ( let i = 1 ; i <= edges . length ; i ++ ) {
44+ states [ i ] = 0
45+ }
46+ return states
47+ }
48+
49+ function createInDegrees ( edges ) {
50+ const inDegrees = { }
51+ for ( let [ srcKey , destKey ] of edges ) {
52+ if ( ! ( destKey in inDegrees ) ) inDegrees [ destKey ] = 1
53+ else inDegrees [ destKey ] ++
54+ }
55+ return inDegrees
56+ }
57+
58+ function createGraph ( edges ) {
59+ const edgesObj = { }
60+ for ( let edge of edges ) {
61+ let srcKey = edge [ 0 ]
62+ let destKey = edge [ 1 ]
63+ if ( ! ( srcKey in edgesObj ) ) edgesObj [ srcKey ] = new Set ( )
64+ edgesObj [ srcKey ] . add ( destKey )
65+ }
66+ return edgesObj
67+ }
68+
69+ function hasMultipleParents ( inDegrees ) {
70+ for ( let key in inDegrees ) {
71+ if ( inDegrees [ key ] > 1 ) return true
72+ }
73+ return false
74+ }
75+
76+ function removeEdge ( edgesObj , srcKey , destKey , inDegrees ) {
77+ edgesObj [ srcKey ] . delete ( destKey )
78+ inDegrees [ destKey ] --
79+ }
80+
81+ function addEdge ( edgesObj , srcKey , destKey , inDegrees ) {
82+ edgesObj [ srcKey ] . add ( destKey )
83+ inDegrees [ destKey ] ++
84+ }
0 commit comments