diff --git a/src/my_project/interviews/top_150_questions_round_22/ex_69_construct_tree_from_preorder_inorder_traversal.py b/src/my_project/interviews/top_150_questions_round_22/ex_69_construct_tree_from_preorder_inorder_traversal.py new file mode 100644 index 00000000..2bd4b802 --- /dev/null +++ b/src/my_project/interviews/top_150_questions_round_22/ex_69_construct_tree_from_preorder_inorder_traversal.py @@ -0,0 +1,39 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + +class Solution: + def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: + # Create a hashmap for quick lookup of indices in inorder + inorder_map = {val: idx for idx, val in enumerate(inorder)} + self.preorder_idx = 0 + + def build(left: int, right: int) -> Optional[TreeNode]: + # Base case: no elements to construct the tree + if left > right: + return None + + # Pick the current root from preorder + root_val = preorder[self.preorder_idx] + root = TreeNode(root_val) + + # Move to the next element in preorder + self.preorder_idx += 1 + + # Find the index of root in inorder to split left and right subtrees + inorder_idx = inorder_map[root_val] + + # Build left subtree (all elements before root in inorder) + root.left = build(left, inorder_idx - 1) + + # Build right subtree (all elements after root in inorder) + root.right = build(inorder_idx + 1, right) + + return root + + return build(0, len(inorder) - 1) \ No newline at end of file diff --git a/src/my_project/interviews/top_150_questions_round_22/ex_70_construct_tree_from_preorder_postorder_traversal.py b/src/my_project/interviews/top_150_questions_round_22/ex_70_construct_tree_from_preorder_postorder_traversal.py new file mode 100644 index 00000000..fbcf0c20 --- /dev/null +++ b/src/my_project/interviews/top_150_questions_round_22/ex_70_construct_tree_from_preorder_postorder_traversal.py @@ -0,0 +1,40 @@ +from typing import List, Union, Collection, Mapping, Optional +from abc import ABC, abstractmethod + +class TreeNode: + def __init__(self, val=0, left=None, right=None): + self.val = val + self.left = left + self.right = right + +class Solution: + def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]: + # Create a hashmap for quick lookup of indices in inorder + inorder_map = {val: idx for idx, val in enumerate(inorder)} + self.postorder_idx = len(postorder) - 1 + + def build(left: int, right: int) -> Optional[TreeNode]: + # Base case: no elements to construct the tree + if left > right: + return None + + # Pick the current root from postorder (from end) + root_val = postorder[self.postorder_idx] + root = TreeNode(root_val) + + # Move to the previous element in postorder + self.postorder_idx -= 1 + + # Find the index of root in inorder to split left and right subtrees + inorder_idx = inorder_map[root_val] + + # Build right subtree first (postorder: left → right → root) + # So when we go backwards, we process root → right → left + root.right = build(inorder_idx + 1, right) + + # Build left subtree + root.left = build(left, inorder_idx - 1) + + return root + + return build(0, len(inorder) - 1) \ No newline at end of file diff --git a/src/my_project/interviews_typescript/top_150_questions_round_1/ex_69_construct_tree_from_preorder_inorder_traversal.ts b/src/my_project/interviews_typescript/top_150_questions_round_1/ex_69_construct_tree_from_preorder_inorder_traversal.ts new file mode 100644 index 00000000..2b76b9d1 --- /dev/null +++ b/src/my_project/interviews_typescript/top_150_questions_round_1/ex_69_construct_tree_from_preorder_inorder_traversal.ts @@ -0,0 +1,37 @@ +import { TreeNode } from './TreeNode'; + +function buildTree(preorder: number[], inorder: number[]): TreeNode | null { + // Create a hashmap for quick lookup of indices in inorder + const inorderMap = new Map(); + inorder.forEach((val, idx) => inorderMap.set(val, idx)); + + let preorderIdx = 0; + + function build(left: number, right: number): TreeNode | null { + // Base case: no elements to construct the tree + if (left > right) { + return null; + } + + // Pick the current root from preorder + const rootVal = preorder[preorderIdx]; + const root = new TreeNode(rootVal); + + // Move to the next element in preorder + preorderIdx++; + + // Find the index of root in inorder to split left and right subtrees + const inorderIdx = inorderMap.get(rootVal)!; + + // Build left subtree (all elements before root in inorder) + root.left = build(left, inorderIdx - 1); + + // Build right subtree (all elements after root in inorder) + root.right = build(inorderIdx + 1, right); + + return root; + } + + return build(0, inorder.length - 1); +} + diff --git a/src/my_project/interviews_typescript/top_150_questions_round_1/ex_70_construct_tree_from_preorder_postorder_traversal.ts b/src/my_project/interviews_typescript/top_150_questions_round_1/ex_70_construct_tree_from_preorder_postorder_traversal.ts new file mode 100644 index 00000000..2207604e --- /dev/null +++ b/src/my_project/interviews_typescript/top_150_questions_round_1/ex_70_construct_tree_from_preorder_postorder_traversal.ts @@ -0,0 +1,38 @@ +import { TreeNode } from './TreeNode'; + +function buildTree(inorder: number[], postorder: number[]): TreeNode | null { + // Create a hashmap for quick lookup of indices in inorder + const inorderMap = new Map(); + inorder.forEach((val, idx) => inorderMap.set(val, idx)); + + let postorderIdx = postorder.length - 1; + + function build(left: number, right: number): TreeNode | null { + // Base case: no elements to construct the tree + if (left > right) { + return null; + } + + // Pick the current root from postorder (from end) + const rootVal = postorder[postorderIdx]; + const root = new TreeNode(rootVal); + + // Move to the previous element in postorder + postorderIdx--; + + // Find the index of root in inorder to split left and right subtrees + const inorderIdx = inorderMap.get(rootVal)!; + + // Build right subtree first (postorder: left → right → root) + // So when we go backwards, we process root → right → left + root.right = build(inorderIdx + 1, right); + + // Build left subtree + root.left = build(left, inorderIdx - 1); + + return root; + } + + return build(0, inorder.length - 1); +} + diff --git a/tests/test_150_questions_round_22/test_69_construct_tree_from_preorder_inorder_traversal_round_22.py b/tests/test_150_questions_round_22/test_69_construct_tree_from_preorder_inorder_traversal_round_22.py new file mode 100644 index 00000000..f976964c --- /dev/null +++ b/tests/test_150_questions_round_22/test_69_construct_tree_from_preorder_inorder_traversal_round_22.py @@ -0,0 +1,53 @@ +import unittest +from typing import Optional, List +from src.my_project.interviews.top_150_questions_round_22\ +.ex_69_construct_tree_from_preorder_inorder_traversal import Solution, TreeNode + +class ConstructTreeFromPreorderInorderTraversalTestCase(unittest.TestCase): + + def tree_to_list(self, root: Optional[TreeNode]) -> List[Optional[int]]: + """Convert tree to level-order list representation with None for missing nodes.""" + if not root: + return [] + + result = [] + queue = [root] + + while queue: + node = queue.pop(0) + if node: + result.append(node.val) + queue.append(node.left) + queue.append(node.right) + else: + result.append(None) + + # Remove trailing None values + while result and result[-1] is None: + result.pop() + + return result + + def test_example_1(self): + """ + Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] + Output: [3,9,20,null,null,15,7] + """ + solution = Solution() + preorder = [3, 9, 20, 15, 7] + inorder = [9, 3, 15, 20, 7] + output = solution.buildTree(preorder, inorder) + expected = [3, 9, 20, None, None, 15, 7] + self.assertEqual(self.tree_to_list(output), expected) + + def test_example_2(self): + """ + Input: preorder = [-1], inorder = [-1] + Output: [-1] + """ + solution = Solution() + preorder = [-1] + inorder = [-1] + output = solution.buildTree(preorder, inorder) + expected = [-1] + self.assertEqual(self.tree_to_list(output), expected) \ No newline at end of file diff --git a/tests/test_150_questions_round_22/test_70_construct_tree_from_preorder_postorder_traversal_round_22.py b/tests/test_150_questions_round_22/test_70_construct_tree_from_preorder_postorder_traversal_round_22.py new file mode 100644 index 00000000..03b47113 --- /dev/null +++ b/tests/test_150_questions_round_22/test_70_construct_tree_from_preorder_postorder_traversal_round_22.py @@ -0,0 +1,53 @@ +import unittest +from typing import Optional, List +from src.my_project.interviews.top_150_questions_round_22\ +.ex_70_construct_tree_from_preorder_postorder_traversal import Solution, TreeNode + +class ConstructTreeFromPreorderPostorderTestCase(unittest.TestCase): + + def tree_to_list(self, root: Optional[TreeNode]) -> List[Optional[int]]: + """Convert tree to level-order list representation with None for missing nodes.""" + if not root: + return [] + + result = [] + queue = [root] + + while queue: + node = queue.pop(0) + if node: + result.append(node.val) + queue.append(node.left) + queue.append(node.right) + else: + result.append(None) + + # Remove trailing None values + while result and result[-1] is None: + result.pop() + + return result + + def test_example_1(self): + """ + Input: inorder = [9,3,15,20,7], postorder = [9,15,7,20,3] + Output: [3,9,20,null,null,15,7] + """ + solution = Solution() + inorder = [9, 3, 15, 20, 7] + postorder = [9, 15, 7, 20, 3] + output = solution.buildTree(inorder, postorder) + expected = [3, 9, 20, None, None, 15, 7] + self.assertEqual(self.tree_to_list(output), expected) + + def test_example_2(self): + """ + Input: inorder = [-1], postorder = [-1] + Output: [-1] + """ + solution = Solution() + inorder = [-1] + postorder = [-1] + output = solution.buildTree(inorder, postorder) + expected = [-1] + self.assertEqual(self.tree_to_list(output), expected) \ No newline at end of file