2
2
* @link Problem export functioninition [[docs/hackerrank/interview_preparation_kit/search/swap-nodes-algo.md]]
3
3
*/
4
4
5
- import { logger as console } from '../../../logger' ;
6
5
import { Node } from '../../lib/Node' ;
7
6
8
7
// CONSTANTS
@@ -11,147 +10,104 @@ export const __ROOT_VALUE__: number = 1;
11
10
export const __LEAF_VALUE__ : number = - 1 ;
12
11
const __RADIX__ = 10 ;
13
12
14
- export function callbackCollectNodes (
15
- root : Node < number > | null | undefined ,
16
- collect : Record < number , Node < number > [ ] > ,
17
- level : number
18
- ) : void {
19
- if ( root ) {
20
- if ( collect ?. [ level ] === undefined ) {
21
- collect [ level ] = [ root ] ;
22
- } else {
23
- collect [ level ] . push ( root ) ;
24
- }
25
- }
26
- }
13
+ export class Tree {
14
+ root : Node < number > ;
27
15
28
- export function callbackCollectFlat (
29
- root : Node < number > | null | undefined ,
30
- collect : Record < number , Node < number > [ ] > ,
31
- level : number
32
- ) : void {
33
- const _level : number = 0 * level ; // set a unique key to use dict as a list
34
- if ( root ) {
35
- if ( collect ?. [ _level ] === undefined ) {
36
- collect [ _level ] = [ root ] ;
37
- } else {
38
- collect [ _level ] . push ( root ) ;
39
- }
40
- }
41
- }
16
+ nodeCollector : Record < number , Node < number > [ ] > ;
17
+
18
+ constructor ( indexes : number [ ] [ ] ) {
19
+ this . root = new Node ( __ROOT_VALUE__ ) ;
20
+ this . nodeCollector = { } ;
21
+ this . nodeCollector [ __INITIAL_LEVEL__ ] = [ this . root ] ;
42
22
43
- export function traverseInOrderCollector (
44
- root : Node < number > | null | undefined ,
45
- collect : Record < number , Node < number > [ ] > ,
46
- level : number ,
47
- callbackFn : (
48
- root : Node < number > | null | undefined ,
49
- collect : Record < number , Node < number > [ ] > ,
50
- level : number
51
- ) => void
52
- ) : Record < number , Node < number > [ ] > {
53
- if ( root ?. left !== null ) {
54
- traverseInOrderCollector ( root ?. left , collect , level + 1 , callbackFn ) ;
23
+ this . buildTree ( indexes ) ;
55
24
}
56
25
57
- callbackFn ( root , collect , level ) ;
26
+ buildTree ( indexes : number [ ] [ ] ) : Tree {
27
+ const indexesCopy = [ ...indexes ] ;
28
+ let currentLevel = __INITIAL_LEVEL__ ;
58
29
59
- if ( root ?. right !== null ) {
60
- traverseInOrderCollector ( root ?. right , collect , level + 1 , callbackFn ) ;
61
- }
30
+ while ( indexesCopy . length > 0 ) {
31
+ const levelSize = Math . min (
32
+ indexesCopy . length ,
33
+ this . nodeCollector [ currentLevel ] ?. length
34
+ ) ;
62
35
63
- return collect ;
64
- }
36
+ const nextLevel = currentLevel + 1 ;
65
37
66
- export function buildTree ( indexes : number [ ] [ ] ) : Node < number > {
67
- const indexesCopy : number [ ] [ ] = [ ...indexes ] ;
68
- const root : Node < number > = new Node < number > ( __ROOT_VALUE__ ) ;
69
- let nodeCollector : Record < number , Node < number > [ ] > = { } ;
70
-
71
- while ( indexesCopy . length > 0 ) {
72
- nodeCollector = { } ;
73
-
74
- traverseInOrderCollector (
75
- root ,
76
- nodeCollector ,
77
- __INITIAL_LEVEL__ ,
78
- callbackCollectNodes
79
- ) ;
80
-
81
- const lastLevel : number = parseInt (
82
- Object . keys ( nodeCollector )
83
- . sort ( ( a , b ) => parseInt ( b , __RADIX__ ) - parseInt ( a , __RADIX__ ) )
84
- . shift ( ) as string ,
85
- __RADIX__
86
- ) ;
87
-
88
- const levelSize = Math . min (
89
- indexesCopy . length ,
90
- nodeCollector [ lastLevel ] ?. length
91
- ) ;
92
- for ( let i = 0 ; i < levelSize ; i ++ ) {
93
- const currentNode : Node < number > = nodeCollector [ lastLevel ] [ i ] ;
94
- const newElement : number [ ] = indexesCopy . shift ( ) as Array < number > ;
95
-
96
- if ( ( newElement ?. [ 0 ] ?? __LEAF_VALUE__ ) !== __LEAF_VALUE__ ) {
97
- currentNode . left = new Node < number > ( newElement [ 0 ] ) ;
38
+ if ( levelSize > 0 ) {
39
+ this . nodeCollector [ nextLevel ] = [ ] ;
98
40
}
99
- if ( ( newElement ?. [ 1 ] ?? __LEAF_VALUE__ ) !== __LEAF_VALUE__ ) {
100
- currentNode . right = new Node < number > ( newElement [ 1 ] ) ;
41
+
42
+ for ( let i = 0 ; i < levelSize ; i ++ ) {
43
+ const currentNode = this . nodeCollector [ currentLevel ] [ i ] ;
44
+ const newElement = indexesCopy ?. shift ( ) ?? [ ] ;
45
+
46
+ if ( ( newElement ?. [ 0 ] ?? __LEAF_VALUE__ ) !== __LEAF_VALUE__ ) {
47
+ currentNode . left = new Node ( newElement [ 0 ] ) ;
48
+ this . nodeCollector [ nextLevel ] . push ( currentNode . left ) ;
49
+ }
50
+ if ( ( newElement ?. [ 1 ] ?? __LEAF_VALUE__ ) !== __LEAF_VALUE__ ) {
51
+ currentNode . right = new Node ( newElement [ 1 ] ) ;
52
+ this . nodeCollector [ nextLevel ] . push ( currentNode . right ) ;
53
+ }
54
+ }
55
+
56
+ if ( this . nodeCollector [ nextLevel ] . length > 0 ) {
57
+ currentLevel = nextLevel ;
101
58
}
102
59
}
60
+
61
+ return this ;
103
62
}
104
63
105
- return root ;
106
- }
64
+ getRoot ( ) : Node < number > {
65
+ return this . root ;
66
+ }
107
67
108
- export function flatTree ( root : Node < number > | null ) : number [ ] {
109
- let nodeCollector : Record < number , Node < number > [ ] > = { } ;
68
+ getCollector ( ) : Record < number , Node < number > [ ] > {
69
+ return this . nodeCollector ;
70
+ }
110
71
111
- nodeCollector = traverseInOrderCollector (
112
- root ,
113
- nodeCollector ,
114
- __INITIAL_LEVEL__ ,
115
- callbackCollectFlat
116
- ) ;
72
+ flatTree ( ) : number [ ] {
73
+ const flatTreeCollector : Node < number > [ ] = [ ] ;
117
74
118
- const lastLevel : number = parseInt (
119
- Object . keys ( nodeCollector )
120
- . sort ( ( a , b ) => parseInt ( b , __RADIX__ ) - parseInt ( a , __RADIX__ ) )
121
- . shift ( ) as string ,
122
- __RADIX__
123
- ) ;
75
+ function traverseInOrderFlat ( node : Node < number > ) : void {
76
+ if ( node ?. left !== null ) {
77
+ traverseInOrderFlat ( node ?. left ) ;
78
+ }
124
79
125
- const output : number [ ] = [ ] ;
126
- nodeCollector [ lastLevel ] . forEach ( ( node : Node < number > ) => {
127
- output . push ( node . data ) ;
128
- } ) ;
80
+ if ( node ) {
81
+ flatTreeCollector . push ( node ) ;
82
+ }
129
83
130
- return output ;
84
+ if ( node ?. right !== null ) {
85
+ traverseInOrderFlat ( node ?. right ) ;
86
+ }
87
+ }
88
+
89
+ traverseInOrderFlat ( this . root ) ;
90
+
91
+ const output : number [ ] = [ ] ;
92
+ flatTreeCollector . forEach ( ( node ) => {
93
+ output . push ( node . data ) ;
94
+ } ) ;
95
+
96
+ return output ;
97
+ }
131
98
}
132
99
133
100
export function swapNodes ( indexes : number [ ] [ ] , queries : number [ ] ) : number [ ] [ ] {
134
- const tree : Node < number > = buildTree ( indexes ) ;
101
+ const tree : Tree = new Tree ( indexes ) ;
102
+ let nodeCollector : Record < number , Node < number > [ ] > = tree . getCollector ( ) ;
135
103
const output : number [ ] [ ] = [ ] ;
136
- let nodeCollector : Record < number , Node < number > [ ] > = { } ;
137
-
138
- traverseInOrderCollector (
139
- tree ,
140
- nodeCollector ,
141
- __INITIAL_LEVEL__ ,
142
- callbackCollectNodes
143
- ) ;
144
104
145
105
nodeCollector = Object . fromEntries (
146
106
Object . entries ( nodeCollector ) . sort (
147
107
( [ a ] , [ b ] ) => parseInt ( a , __RADIX__ ) - parseInt ( b , __RADIX__ )
148
108
)
149
109
) ;
150
110
151
- let flattenedTree : number [ ] = flatTree ( tree ) ;
152
-
153
- console . debug ( `Plain tree: ${ flattenedTree } ` ) ;
154
-
155
111
for ( const query of queries ) {
156
112
for ( const [ level , nodeList ] of Object . entries ( nodeCollector ) ) {
157
113
const tLevel : number = parseInt ( level , __RADIX__ ) ;
@@ -164,8 +120,7 @@ export function swapNodes(indexes: number[][], queries: number[]): number[][] {
164
120
}
165
121
}
166
122
167
- flattenedTree = flatTree ( tree ) ;
168
- output . push ( flattenedTree ) ;
123
+ output . push ( tree . flatTree ( ) ) ;
169
124
}
170
125
171
126
return output ;
0 commit comments