Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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<number, number>();
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);
}

Original file line number Diff line number Diff line change
@@ -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<number, number>();
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);
}

Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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)