From 1b9766167704f4806e76c64a1a6904fe4aa0b99c Mon Sep 17 00:00:00 2001 From: TheGeniusOfEternity Date: Thu, 27 Aug 2026 15:57:22 +0300 Subject: [PATCH 1/4] test(neetcode|interview|find-by-type): testcases --- src/interview/find-by-type/solution.test.ts | 113 ++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/interview/find-by-type/solution.test.ts diff --git a/src/interview/find-by-type/solution.test.ts b/src/interview/find-by-type/solution.test.ts new file mode 100644 index 0000000..9a1632c --- /dev/null +++ b/src/interview/find-by-type/solution.test.ts @@ -0,0 +1,113 @@ +import { findByType } from './solution'; + +describe('Find By Type | Interview | Testcases', () => { + test('#1 Follow upside-down order', () => { + const tree = { + type: 'folder', + name: 'root', + children: [ + { type: 'file', name: 'file-1', children: [] }, + { + type: 'folder', + name: 'docs', + children: [{ type: 'file', name: 'file-2', children: [] }], + }, + { type: 'file', name: 'file-3', children: [] }, + ], + }; + expect(findByType(tree, 'file').map((node) => node.name)).toEqual([ + 'file-1', + 'file-2', + 'file-3', + ]); + }); + + test('#2 No nodes of requested type', () => { + const tree = { + type: 'folder', + name: 'root', + children: [ + { type: 'folder', name: 'sub1', children: [] }, + { type: 'folder', name: 'sub2', children: [] }, + ], + }; + expect(findByType(tree, 'file')).toEqual([]); + }); + + test('#3 All nodes are of requested type', () => { + const tree = { + type: 'file', + name: 'root-file', + children: [ + { type: 'file', name: 'file-a', children: [] }, + { type: 'file', name: 'file-b', children: [] }, + ], + }; + expect(findByType(tree, 'file').map((node) => node.name)).toEqual([ + 'root-file', + 'file-a', + 'file-b', + ]); + }); + + test('#4 Deep nesting', () => { + const tree = { + type: 'folder', + name: 'root', + children: [ + { + type: 'folder', + name: 'level1', + children: [ + { + type: 'folder', + name: 'level2', + children: [{ type: 'file', name: 'deep-file', children: [] }], + }, + ], + }, + ], + }; + expect(findByType(tree, 'file').map((node) => node.name)).toEqual([ + 'deep-file', + ]); + }); + + test('#5 Multiple matches in different branches', () => { + const tree = { + type: 'folder', + name: 'root', + children: [ + { + type: 'folder', + name: 'branch1', + children: [ + { type: 'file', name: 'b1-f1', children: [] }, + { type: 'file', name: 'b1-f2', children: [] }, + ], + }, + { + type: 'folder', + name: 'branch2', + children: [{ type: 'file', name: 'b2-f1', children: [] }], + }, + ], + }; + expect(findByType(tree, 'file').map((node) => node.name)).toEqual([ + 'b1-f1', + 'b1-f2', + 'b2-f1', + ]); + }); + + test('#6 Search for type that appears only in root', () => { + const tree = { + type: 'special', + name: 'root-special', + children: [{ type: 'file', name: 'file-1', children: [] }], + }; + expect(findByType(tree, 'special').map((node) => node.name)).toEqual([ + 'root-special', + ]); + }); +}); From 3094aad21c2622adb882100097a4c332e896ba8a Mon Sep 17 00:00:00 2001 From: TheGeniusOfEternity Date: Thu, 27 Aug 2026 15:57:34 +0300 Subject: [PATCH 2/4] feat(neetcode|interview|find-by-type): recursive solution --- src/interview/find-by-type/solution.ts | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/interview/find-by-type/solution.ts diff --git a/src/interview/find-by-type/solution.ts b/src/interview/find-by-type/solution.ts new file mode 100644 index 0000000..269173e --- /dev/null +++ b/src/interview/find-by-type/solution.ts @@ -0,0 +1,43 @@ +interface Tree { + type: string; + name: string; + children: Tree[]; +} + +/** + * @param tree - nested object of nodes + * @param type - searching param to find nodes + * + * @example + * + * const tree = { + * type: 'folder', + * name: 'root', + * children: [ + * { type: 'file', name: 'file-1', children: [] }, + * { + * type: 'folder', + * name: 'docs', + * children: [{ type: 'file', name: 'file-2', children: [] }], + * }, + * { type: 'file', name: 'file-3', children: [] }, + * ], + * }; + * + * console.log(findByType(tree, 'file').map((node) => node.name)); + * // Expected: ["file-1", "file-2", "file-3"] + */ +export const findByType = (tree: Tree, type: string): Tree[] => { + const matches: Tree[] = []; + const dfs = (node: Tree): void => { + if (node.type === type) { + matches.push(node); + } + node.children.forEach((child: Tree) => { + dfs(child); + }); + }; + dfs(tree); + + return matches; +}; From ede68545569a78dfff6aefc20f8547e5ac73163a Mon Sep 17 00:00:00 2001 From: TheGeniusOfEternity Date: Thu, 27 Aug 2026 16:00:21 +0300 Subject: [PATCH 3/4] feat(neetcode|interview|find-by-type): iterative solution --- src/interview/find-by-type/solution.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/interview/find-by-type/solution.ts b/src/interview/find-by-type/solution.ts index 269173e..c96fe43 100644 --- a/src/interview/find-by-type/solution.ts +++ b/src/interview/find-by-type/solution.ts @@ -29,15 +29,20 @@ interface Tree { */ export const findByType = (tree: Tree, type: string): Tree[] => { const matches: Tree[] = []; - const dfs = (node: Tree): void => { - if (node.type === type) { - matches.push(node); + const stack: Tree[] = [tree]; + + while (stack.length) { + const node = stack.pop(); + if (node) { + if (node.type === type) { + matches.push(node); + } + + for (let i = node.children.length - 1; i >= 0; i--) { + stack.push(node.children[i]); + } } - node.children.forEach((child: Tree) => { - dfs(child); - }); - }; - dfs(tree); + } return matches; }; From 951b7080832189068ce94001274a19cabed403a9 Mon Sep 17 00:00:00 2001 From: TheGeniusOfEternity Date: Thu, 27 Aug 2026 16:00:32 +0300 Subject: [PATCH 4/4] feat(neetcode|interview): update table of contents --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f06bd83..ef9e775 100644 --- a/README.md +++ b/README.md @@ -132,4 +132,5 @@ Interview Questions - [Task #10](src/interview/render-items/with-async) - _Render Items: With Async_ - [Task #11](src/interview/build-tree/no-replies-sort) - _Build Tree: No Replies Sort_ - [Task #12](src/interview/build-tree/with-replies-sort) - _Build Tree: With Replies Sort_ -- [Task #13](src/interview/build-comments-tree) - _Build Comments Tree_ \ No newline at end of file +- [Task #13](src/interview/build-comments-tree) - _Build Comments Tree_ +- [Task #13](src/interview/find-by-type) - _Find By Type_ \ No newline at end of file