22 * @link Problem export functioninition [[docs/hackerrank/interview_preparation_kit/search/swap-nodes-algo.md]]
33 */
44
5- import { logger as console } from '../../../logger' ;
65import { Node } from '../../lib/Node' ;
76
87// CONSTANTS
@@ -11,147 +10,104 @@ export const __ROOT_VALUE__: number = 1;
1110export const __LEAF_VALUE__ : number = - 1 ;
1211const __RADIX__ = 10 ;
1312
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 > ;
2715
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 ] ;
4222
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 ) ;
5524 }
5625
57- callbackFn ( root , collect , level ) ;
26+ buildTree ( indexes : number [ ] [ ] ) : Tree {
27+ const indexesCopy = [ ...indexes ] ;
28+ let currentLevel = __INITIAL_LEVEL__ ;
5829
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+ ) ;
6235
63- return collect ;
64- }
36+ const nextLevel = currentLevel + 1 ;
6537
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 ] = [ ] ;
9840 }
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 ;
10158 }
10259 }
60+
61+ return this ;
10362 }
10463
105- return root ;
106- }
64+ getRoot ( ) : Node < number > {
65+ return this . root ;
66+ }
10767
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+ }
11071
111- nodeCollector = traverseInOrderCollector (
112- root ,
113- nodeCollector ,
114- __INITIAL_LEVEL__ ,
115- callbackCollectFlat
116- ) ;
72+ flatTree ( ) : number [ ] {
73+ const flatTreeCollector : Node < number > [ ] = [ ] ;
11774
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+ }
12479
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+ }
12983
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+ }
13198}
13299
133100export 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 ( ) ;
135103 const output : number [ ] [ ] = [ ] ;
136- let nodeCollector : Record < number , Node < number > [ ] > = { } ;
137-
138- traverseInOrderCollector (
139- tree ,
140- nodeCollector ,
141- __INITIAL_LEVEL__ ,
142- callbackCollectNodes
143- ) ;
144104
145105 nodeCollector = Object . fromEntries (
146106 Object . entries ( nodeCollector ) . sort (
147107 ( [ a ] , [ b ] ) => parseInt ( a , __RADIX__ ) - parseInt ( b , __RADIX__ )
148108 )
149109 ) ;
150110
151- let flattenedTree : number [ ] = flatTree ( tree ) ;
152-
153- console . debug ( `Plain tree: ${ flattenedTree } ` ) ;
154-
155111 for ( const query of queries ) {
156112 for ( const [ level , nodeList ] of Object . entries ( nodeCollector ) ) {
157113 const tLevel : number = parseInt ( level , __RADIX__ ) ;
@@ -164,8 +120,7 @@ export function swapNodes(indexes: number[][], queries: number[]): number[][] {
164120 }
165121 }
166122
167- flattenedTree = flatTree ( tree ) ;
168- output . push ( flattenedTree ) ;
123+ output . push ( tree . flatTree ( ) ) ;
169124 }
170125
171126 return output ;
0 commit comments