Skip to content

Commit 650457b

Browse files
author
Gonzalo Diaz
committed
[Hacker Rank] Interview Preparation Kit: Search: Swap Nodes [Algo]. First solution.
1 parent b062507 commit 650457b

File tree

3 files changed

+114
-28
lines changed

3 files changed

+114
-28
lines changed

src/hackerrank/interview_preparation_kit/search/swap_nodes_algo.test.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { describe, expect, it } from '@jest/globals';
22

3-
import { build_tree, flat_tree } from './swap_nodes_algo';
3+
import { Node } from '../../lib/Node';
4+
import {
5+
build_tree,
6+
flat_tree,
7+
swap_branch,
8+
swapNodes,
9+
__INITIAL_LEVEL__
10+
} from './swap_nodes_algo';
411
import TEST_CASES from './swap_nodes_algo.testcases.json';
512

613
describe('swap_nodes_algo', () => {
@@ -26,6 +33,28 @@ describe('swap_nodes_algo', () => {
2633
expect(t_result).toStrictEqual(expected);
2734
});
2835

36+
it('test_swap_branch empty', () => {
37+
expect.assertions(1);
38+
39+
const t_input: null = null;
40+
const t_result: Node<number> | null = swap_branch(t_input);
41+
const expected = null;
42+
43+
expect(t_result).toStrictEqual(expected);
44+
});
45+
46+
it('test_swap_branch', () => {
47+
expect.assertions(1);
48+
49+
const t_input: Node<number> = new Node<number>(__INITIAL_LEVEL__);
50+
t_input.left = new Node<number>(2);
51+
t_input.right = new Node<number>(3);
52+
const t_result: number[] = flat_tree(swap_branch(t_input));
53+
const expected: number[] = [3, 1, 2];
54+
55+
expect(t_result).toStrictEqual(expected);
56+
});
57+
2958
it('build_tree and plain test cases', () => {
3059
expect.assertions(4);
3160

@@ -36,4 +65,14 @@ describe('swap_nodes_algo', () => {
3665
expect(t_result).toStrictEqual(test.plain);
3766
});
3867
});
68+
69+
it('swapNodes test cases', () => {
70+
expect.assertions(4);
71+
72+
TEST_CASES.forEach((test) => {
73+
const t_result: number[][] = swapNodes(test.nodes, test.queries);
74+
75+
expect(t_result).toStrictEqual(test.expected);
76+
});
77+
});
3978
});

src/hackerrank/interview_preparation_kit/search/swap_nodes_algo.testcases.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,22 @@
44
"nodes": [[2, 3], [-1, -1], [-1, -1]],
55
"plain": [2, 1, 3],
66
"queries": [1, 1],
7-
"answer": [[3, 1, 2], [2, 1, 3]]
7+
"expected": [[3, 1, 2], [2, 1, 3]]
88
},
99
{
1010
"title": "Sample 1",
1111
"nodes": [[2, 3], [-1, 4], [-1, 5], [-1, -1], [-1, -1]],
1212
"plain": [2, 4, 1, 3, 5],
1313
"queries": [2],
14-
"answer": [[4, 2, 1, 5, 3]]
14+
"expected": [[4, 2, 1, 5, 3]]
1515
},
1616
{
1717
"title": "Sample 2",
1818
"nodes": [[2, 3], [4, -1], [5, -1], [6, -1], [7, 8], [-1, 9],
1919
[-1, -1], [10, 11], [-1, -1], [-1, -1], [-1, -1]],
2020
"plain": [6, 9, 4, 2, 1, 7, 5, 10, 8, 11, 3],
2121
"queries": [2, 4],
22-
"answer": [[2, 9, 6, 4, 1, 3, 7, 5, 11, 8, 10],
22+
"expected": [[2, 9, 6, 4, 1, 3, 7, 5, 11, 8, 10],
2323
[2, 6, 9, 4, 1, 3, 7, 5, 10, 8, 11]]
2424
},
2525
{
@@ -29,7 +29,7 @@
2929
[-1, -1], [-1, -1], [-1, -1], [-1, -1]],
3030
"plain": [4, 12, 7, 13, 2, 8, 14, 5, 9, 1, 15, 10, 6, 16, 11, 17, 3],
3131
"queries": [2, 3],
32-
"answer": [[14, 8, 5, 9, 2, 4, 13, 7, 12, 1, 3, 10, 15, 6, 17, 11, 16],
32+
"expected": [[14, 8, 5, 9, 2, 4, 13, 7, 12, 1, 3, 10, 15, 6, 17, 11, 16],
3333
[9, 5, 14, 8, 2, 13, 7, 12, 4, 1, 3, 17, 11, 16, 6, 10, 15]]
3434
}
3535
]

src/hackerrank/interview_preparation_kit/search/swap_nodes_algo.ts

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,61 @@
22
* @link Problem export functioninition [[docs/hackerrank/interview_preparation_kit/search/swap-nodes-algo.md]]
33
*/
44

5+
import { logger as console } from '../../../logger';
56
import { Node } from '../../lib/Node';
67

78
// CONSTANTS
8-
const __INITIAL_LEVEL__: number = 1;
9-
const __ROOT_VALUE__: number = 1;
10-
const __LEAF_VALUE__: number = -1;
9+
export const __INITIAL_LEVEL__: number = 1;
10+
export const __ROOT_VALUE__: number = 1;
11+
export const __LEAF_VALUE__: number = -1;
1112

1213
export function callback_collect_nodes(
13-
root: Node<number>,
14+
root: Node<number> | null | undefined,
1415
collect: Record<number, Node<number>[]>,
1516
level: number
1617
): void {
17-
if (collect?.[level] === undefined) {
18-
collect[level] = [root];
19-
} else {
20-
collect[level].push(root);
18+
if (root) {
19+
if (collect?.[level] === undefined) {
20+
collect[level] = [root];
21+
} else {
22+
collect[level].push(root);
23+
}
2124
}
2225
}
2326

2427
export function callback_collect_flat(
25-
root: Node<number>,
28+
root: Node<number> | null | undefined,
2629
collect: Record<number, Node<number>[]>,
2730
level: number
2831
): void {
2932
const _level: number = 0 * level; // set a unique key to use dict as a list
30-
31-
if (collect?.[_level] === undefined) {
32-
collect[_level] = [root];
33-
} else {
34-
collect[_level].push(root);
33+
if (root) {
34+
if (collect?.[_level] === undefined) {
35+
collect[_level] = [root];
36+
} else {
37+
collect[_level].push(root);
38+
}
3539
}
3640
}
3741

3842
export function traverse_in_order_collector(
39-
root: Node<number>,
43+
root: Node<number> | null | undefined,
4044
collect: Record<number, Node<number>[]>,
4145
level: number,
4246
callbackFn: (
43-
root: Node<number>,
47+
root: Node<number> | null | undefined,
4448
collect: Record<number, Node<number>[]>,
4549
level: number
4650
) => void
4751
): Record<number, Node<number>[]> {
48-
if (root.left !== null) {
49-
traverse_in_order_collector(root.left, collect, level + 1, callbackFn);
52+
if (root?.left !== null) {
53+
traverse_in_order_collector(root?.left, collect, level + 1, callbackFn);
5054
}
5155

5256
callbackFn(root, collect, level);
5357

54-
if (root.right !== null) {
55-
traverse_in_order_collector(root.right, collect, level + 1, callbackFn);
58+
if (root?.right !== null) {
59+
traverse_in_order_collector(root?.right, collect, level + 1, callbackFn);
5660
}
5761

5862
return collect;
@@ -97,7 +101,7 @@ export function build_tree(indexes: number[][]): Node<number> {
97101
return root;
98102
}
99103

100-
export function flat_tree(root: Node<number>): number[] {
104+
export function flat_tree(root: Node<number> | null): number[] {
101105
let node_collector: Record<number, Node<number>[]> = {};
102106

103107
node_collector = traverse_in_order_collector(
@@ -121,8 +125,51 @@ export function flat_tree(root: Node<number>): number[] {
121125
return output;
122126
}
123127

128+
export function swap_branch(root: Node<number> | null): Node<number> | null {
129+
if (root) {
130+
[root.left, root.right] = [root.right, root.left];
131+
}
132+
133+
return root;
134+
}
135+
124136
export function swapNodes(indexes: number[][], queries: number[]): number[][] {
125-
return [];
137+
const tree: Node<number> = build_tree(indexes);
138+
139+
const output: number[][] = [];
140+
let node_collector: Record<number, Node<number>[]> = {};
141+
142+
traverse_in_order_collector(
143+
tree,
144+
node_collector,
145+
__INITIAL_LEVEL__,
146+
callback_collect_nodes
147+
);
148+
149+
node_collector = Object.fromEntries(
150+
Object.entries(node_collector).sort(([a], [b]) => parseInt(a) - parseInt(b))
151+
);
152+
153+
let flattened_tree: number[] = flat_tree(tree);
154+
155+
console.debug(`Plain tree: ${flattened_tree}`);
156+
157+
for (const query in queries) {
158+
for (const [level, node_list] of Object.entries(node_collector)) {
159+
const t_level: number = parseInt(level);
160+
161+
if (t_level % queries[query] == 0) {
162+
for (const node of node_list) {
163+
swap_branch(node);
164+
}
165+
}
166+
}
167+
168+
flattened_tree = flat_tree(tree);
169+
output.push(flattened_tree);
170+
}
171+
172+
return output;
126173
}
127174

128-
export default { swapNodes };
175+
export default { swapNodes, __INITIAL_LEVEL__ };

0 commit comments

Comments
 (0)