Skip to content

Commit 2f83f5b

Browse files
authored
Merge pull request #1541 from ivanpenaloza/february07
adding algo
2 parents d71d760 + 91c15f5 commit 2f83f5b

File tree

6 files changed

+260
-0
lines changed

6 files changed

+260
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from typing import List, Union, Collection, Mapping, Optional
2+
from abc import ABC, abstractmethod
3+
4+
class TreeNode:
5+
def __init__(self, val=0, left=None, right=None):
6+
self.val = val
7+
self.left = left
8+
self.right = right
9+
10+
class Solution:
11+
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
12+
# Create a hashmap for quick lookup of indices in inorder
13+
inorder_map = {val: idx for idx, val in enumerate(inorder)}
14+
self.preorder_idx = 0
15+
16+
def build(left: int, right: int) -> Optional[TreeNode]:
17+
# Base case: no elements to construct the tree
18+
if left > right:
19+
return None
20+
21+
# Pick the current root from preorder
22+
root_val = preorder[self.preorder_idx]
23+
root = TreeNode(root_val)
24+
25+
# Move to the next element in preorder
26+
self.preorder_idx += 1
27+
28+
# Find the index of root in inorder to split left and right subtrees
29+
inorder_idx = inorder_map[root_val]
30+
31+
# Build left subtree (all elements before root in inorder)
32+
root.left = build(left, inorder_idx - 1)
33+
34+
# Build right subtree (all elements after root in inorder)
35+
root.right = build(inorder_idx + 1, right)
36+
37+
return root
38+
39+
return build(0, len(inorder) - 1)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from typing import List, Union, Collection, Mapping, Optional
2+
from abc import ABC, abstractmethod
3+
4+
class TreeNode:
5+
def __init__(self, val=0, left=None, right=None):
6+
self.val = val
7+
self.left = left
8+
self.right = right
9+
10+
class Solution:
11+
def buildTree(self, inorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
12+
# Create a hashmap for quick lookup of indices in inorder
13+
inorder_map = {val: idx for idx, val in enumerate(inorder)}
14+
self.postorder_idx = len(postorder) - 1
15+
16+
def build(left: int, right: int) -> Optional[TreeNode]:
17+
# Base case: no elements to construct the tree
18+
if left > right:
19+
return None
20+
21+
# Pick the current root from postorder (from end)
22+
root_val = postorder[self.postorder_idx]
23+
root = TreeNode(root_val)
24+
25+
# Move to the previous element in postorder
26+
self.postorder_idx -= 1
27+
28+
# Find the index of root in inorder to split left and right subtrees
29+
inorder_idx = inorder_map[root_val]
30+
31+
# Build right subtree first (postorder: left → right → root)
32+
# So when we go backwards, we process root → right → left
33+
root.right = build(inorder_idx + 1, right)
34+
35+
# Build left subtree
36+
root.left = build(left, inorder_idx - 1)
37+
38+
return root
39+
40+
return build(0, len(inorder) - 1)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { TreeNode } from './TreeNode';
2+
3+
function buildTree(preorder: number[], inorder: number[]): TreeNode | null {
4+
// Create a hashmap for quick lookup of indices in inorder
5+
const inorderMap = new Map<number, number>();
6+
inorder.forEach((val, idx) => inorderMap.set(val, idx));
7+
8+
let preorderIdx = 0;
9+
10+
function build(left: number, right: number): TreeNode | null {
11+
// Base case: no elements to construct the tree
12+
if (left > right) {
13+
return null;
14+
}
15+
16+
// Pick the current root from preorder
17+
const rootVal = preorder[preorderIdx];
18+
const root = new TreeNode(rootVal);
19+
20+
// Move to the next element in preorder
21+
preorderIdx++;
22+
23+
// Find the index of root in inorder to split left and right subtrees
24+
const inorderIdx = inorderMap.get(rootVal)!;
25+
26+
// Build left subtree (all elements before root in inorder)
27+
root.left = build(left, inorderIdx - 1);
28+
29+
// Build right subtree (all elements after root in inorder)
30+
root.right = build(inorderIdx + 1, right);
31+
32+
return root;
33+
}
34+
35+
return build(0, inorder.length - 1);
36+
}
37+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { TreeNode } from './TreeNode';
2+
3+
function buildTree(inorder: number[], postorder: number[]): TreeNode | null {
4+
// Create a hashmap for quick lookup of indices in inorder
5+
const inorderMap = new Map<number, number>();
6+
inorder.forEach((val, idx) => inorderMap.set(val, idx));
7+
8+
let postorderIdx = postorder.length - 1;
9+
10+
function build(left: number, right: number): TreeNode | null {
11+
// Base case: no elements to construct the tree
12+
if (left > right) {
13+
return null;
14+
}
15+
16+
// Pick the current root from postorder (from end)
17+
const rootVal = postorder[postorderIdx];
18+
const root = new TreeNode(rootVal);
19+
20+
// Move to the previous element in postorder
21+
postorderIdx--;
22+
23+
// Find the index of root in inorder to split left and right subtrees
24+
const inorderIdx = inorderMap.get(rootVal)!;
25+
26+
// Build right subtree first (postorder: left → right → root)
27+
// So when we go backwards, we process root → right → left
28+
root.right = build(inorderIdx + 1, right);
29+
30+
// Build left subtree
31+
root.left = build(left, inorderIdx - 1);
32+
33+
return root;
34+
}
35+
36+
return build(0, inorder.length - 1);
37+
}
38+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import unittest
2+
from typing import Optional, List
3+
from src.my_project.interviews.top_150_questions_round_22\
4+
.ex_69_construct_tree_from_preorder_inorder_traversal import Solution, TreeNode
5+
6+
class ConstructTreeFromPreorderInorderTraversalTestCase(unittest.TestCase):
7+
8+
def tree_to_list(self, root: Optional[TreeNode]) -> List[Optional[int]]:
9+
"""Convert tree to level-order list representation with None for missing nodes."""
10+
if not root:
11+
return []
12+
13+
result = []
14+
queue = [root]
15+
16+
while queue:
17+
node = queue.pop(0)
18+
if node:
19+
result.append(node.val)
20+
queue.append(node.left)
21+
queue.append(node.right)
22+
else:
23+
result.append(None)
24+
25+
# Remove trailing None values
26+
while result and result[-1] is None:
27+
result.pop()
28+
29+
return result
30+
31+
def test_example_1(self):
32+
"""
33+
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
34+
Output: [3,9,20,null,null,15,7]
35+
"""
36+
solution = Solution()
37+
preorder = [3, 9, 20, 15, 7]
38+
inorder = [9, 3, 15, 20, 7]
39+
output = solution.buildTree(preorder, inorder)
40+
expected = [3, 9, 20, None, None, 15, 7]
41+
self.assertEqual(self.tree_to_list(output), expected)
42+
43+
def test_example_2(self):
44+
"""
45+
Input: preorder = [-1], inorder = [-1]
46+
Output: [-1]
47+
"""
48+
solution = Solution()
49+
preorder = [-1]
50+
inorder = [-1]
51+
output = solution.buildTree(preorder, inorder)
52+
expected = [-1]
53+
self.assertEqual(self.tree_to_list(output), expected)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import unittest
2+
from typing import Optional, List
3+
from src.my_project.interviews.top_150_questions_round_22\
4+
.ex_70_construct_tree_from_preorder_postorder_traversal import Solution, TreeNode
5+
6+
class ConstructTreeFromPreorderPostorderTestCase(unittest.TestCase):
7+
8+
def tree_to_list(self, root: Optional[TreeNode]) -> List[Optional[int]]:
9+
"""Convert tree to level-order list representation with None for missing nodes."""
10+
if not root:
11+
return []
12+
13+
result = []
14+
queue = [root]
15+
16+
while queue:
17+
node = queue.pop(0)
18+
if node:
19+
result.append(node.val)
20+
queue.append(node.left)
21+
queue.append(node.right)
22+
else:
23+
result.append(None)
24+
25+
# Remove trailing None values
26+
while result and result[-1] is None:
27+
result.pop()
28+
29+
return result
30+
31+
def test_example_1(self):
32+
"""
33+
Input: inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
34+
Output: [3,9,20,null,null,15,7]
35+
"""
36+
solution = Solution()
37+
inorder = [9, 3, 15, 20, 7]
38+
postorder = [9, 15, 7, 20, 3]
39+
output = solution.buildTree(inorder, postorder)
40+
expected = [3, 9, 20, None, None, 15, 7]
41+
self.assertEqual(self.tree_to_list(output), expected)
42+
43+
def test_example_2(self):
44+
"""
45+
Input: inorder = [-1], postorder = [-1]
46+
Output: [-1]
47+
"""
48+
solution = Solution()
49+
inorder = [-1]
50+
postorder = [-1]
51+
output = solution.buildTree(inorder, postorder)
52+
expected = [-1]
53+
self.assertEqual(self.tree_to_list(output), expected)

0 commit comments

Comments
 (0)