Skip to content

Commit 4a0c7c6

Browse files
committed
Create Binary Tree From Descriptions
1 parent 27eed64 commit 4a0c7c6

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# 2196. Create Binary Tree From Descriptions
2+
# Topics: 'Array', 'Tree', 'Hash Table', 'Binary Tree'
3+
# Level: 'Medium'
4+
5+
# You are given a 2D integer array descriptions where descriptions[i] = [parenti, childi, isLefti] indicates that parenti is the parent of childi in a binary tree of unique values. Furthermore,
6+
7+
# If isLefti == 1, then childi is the left child of parenti.
8+
# If isLefti == 0, then childi is the right child of parenti.
9+
10+
# Construct the binary tree described by descriptions and return its root.
11+
12+
# The test cases will be generated such that the binary tree is valid.
13+
14+
15+
16+
# Example 1:
17+
18+
# Input: descriptions = [[20,15,1],[20,17,0],[50,20,1],[50,80,0],[80,19,1]]
19+
# Output: [50,20,80,15,17,19]
20+
# Explanation: The root node is the node with value 50 since it has no parent.
21+
# The resulting binary tree is shown in the diagram.
22+
23+
# Example 2:
24+
25+
# Input: descriptions = [[1,2,1],[2,3,0],[3,4,1]]
26+
# Output: [1,2,null,null,3,4]
27+
# Explanation: The root node is the node with value 1 since it has no parent.
28+
# The resulting binary tree is shown in the diagram.
29+
30+
# Constraints:
31+
32+
# 1 <= descriptions.length <= 104
33+
# descriptions[i].length == 3
34+
# 1 <= parenti, childi <= 105
35+
# 0 <= isLefti <= 1
36+
# The binary tree described by descriptions is valid.
37+
38+
# Definition for a binary tree node.
39+
from collections import defaultdict
40+
from typing import List, Optional
41+
42+
class TreeNode:
43+
def __init__(self, val=0, left=None, right=None):
44+
self.val = val
45+
self.left = left
46+
self.right = right
47+
48+
class Solution:
49+
def createBinaryTree(self, descriptions: List[List[int]]) -> Optional[TreeNode]:
50+
d = defaultdict(TreeNode)
51+
childs = set()
52+
for pid, chid, isleft in descriptions:
53+
parent = d[pid]
54+
parent.val = pid
55+
child = d[chid]
56+
child.val = chid
57+
if isleft:
58+
parent.left = child
59+
else:
60+
parent.right = child
61+
d[pid] = parent
62+
childs.add(chid)
63+
64+
for nodeid, node in d.items():
65+
if nodeid not in childs:
66+
return node
67+
68+
return None
69+
70+
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
from collections import defaultdict
2+
from typing import List, Optional
3+
from create import Solution, TreeNode
4+
5+
# Helper functions for testing
6+
def tree_to_list(root: Optional[TreeNode]) -> List[Optional[int]]:
7+
"""Convert tree to level-order list representation (BFS)"""
8+
if not root:
9+
return []
10+
11+
result = []
12+
queue = [root]
13+
14+
while queue:
15+
node = queue.pop(0)
16+
if node:
17+
result.append(node.val)
18+
queue.append(node.left)
19+
queue.append(node.right)
20+
else:
21+
result.append(None)
22+
23+
# Remove trailing None values
24+
while result and result[-1] is None:
25+
result.pop()
26+
27+
return result
28+
29+
30+
def print_tree(root: Optional[TreeNode], level=0, prefix="Root: "):
31+
"""Print tree structure in a readable format"""
32+
if root is not None:
33+
print(" " * (level * 4) + prefix + str(root.val))
34+
if root.left or root.right:
35+
if root.left:
36+
print_tree(root.left, level + 1, "L--- ")
37+
else:
38+
print(" " * ((level + 1) * 4) + "L--- None")
39+
if root.right:
40+
print_tree(root.right, level + 1, "R--- ")
41+
else:
42+
print(" " * ((level + 1) * 4) + "R--- None")
43+
44+
45+
def run_tests():
46+
solution = Solution()
47+
48+
# Test 1: Example 1 from problem
49+
print("Test 1: Multiple levels with full tree")
50+
descriptions1 = [[20,15,1],[20,17,0],[50,20,1],[50,80,0],[80,19,1]]
51+
root1 = solution.createBinaryTree(descriptions1)
52+
result1 = tree_to_list(root1)
53+
print(f"Input: {descriptions1}")
54+
print(f"Output: {result1}")
55+
print(f"Expected: [50, 20, 80, 15, 17, 19]")
56+
print_tree(root1)
57+
print()
58+
59+
# Test 2: Example 2 from problem
60+
print("Test 2: Linear tree with sparse nodes")
61+
descriptions2 = [[1,2,1],[2,3,0],[3,4,1]]
62+
root2 = solution.createBinaryTree(descriptions2)
63+
result2 = tree_to_list(root2)
64+
print(f"Input: {descriptions2}")
65+
print(f"Output: {result2}")
66+
print(f"Expected: [1, 2, None, None, 3, 4]")
67+
print_tree(root2)
68+
print()
69+
70+
# Test 3: Single parent with two children
71+
print("Test 3: Simple tree - one parent, two children")
72+
descriptions3 = [[1,2,1],[1,3,0]]
73+
root3 = solution.createBinaryTree(descriptions3)
74+
result3 = tree_to_list(root3)
75+
print(f"Input: {descriptions3}")
76+
print(f"Output: {result3}")
77+
print(f"Expected: [1, 2, 3]")
78+
print_tree(root3)
79+
print()
80+
81+
# Test 4: Only left children
82+
print("Test 4: Only left children chain")
83+
descriptions4 = [[1,2,1],[2,3,1],[3,4,1]]
84+
root4 = solution.createBinaryTree(descriptions4)
85+
result4 = tree_to_list(root4)
86+
print(f"Input: {descriptions4}")
87+
print(f"Output: {result4}")
88+
print(f"Expected: [1, 2, None, 3, None, 4]")
89+
print_tree(root4)
90+
print()
91+
92+
# Test 5: Only right children
93+
print("Test 5: Only right children chain")
94+
descriptions5 = [[1,2,0],[2,3,0],[3,4,0]]
95+
root5 = solution.createBinaryTree(descriptions5)
96+
result5 = tree_to_list(root5)
97+
print(f"Input: {descriptions5}")
98+
print(f"Output: {result5}")
99+
print(f"Expected: [1, None, 2, None, 3, None, 4]")
100+
print_tree(root5)
101+
print()
102+
103+
# Test 6: Single node
104+
print("Test 6: Single parent-child relationship")
105+
descriptions6 = [[1,2,1]]
106+
root6 = solution.createBinaryTree(descriptions6)
107+
result6 = tree_to_list(root6)
108+
print(f"Input: {descriptions6}")
109+
print(f"Output: {result6}")
110+
print(f"Expected: [1, 2]")
111+
print_tree(root6)
112+
print()
113+
114+
# Test 7: Larger values
115+
print("Test 7: Large node values")
116+
descriptions7 = [[100000,50000,1],[100000,75000,0],[50000,25000,1]]
117+
root7 = solution.createBinaryTree(descriptions7)
118+
result7 = tree_to_list(root7)
119+
print(f"Input: {descriptions7}")
120+
print(f"Output: {result7}")
121+
print(f"Expected: [100000, 50000, 75000, 25000]")
122+
print_tree(root7)
123+
print()
124+
125+
# Test 8: Unordered descriptions
126+
print("Test 8: Descriptions in random order")
127+
descriptions8 = [[3,4,0],[1,2,1],[2,3,0]]
128+
root8 = solution.createBinaryTree(descriptions8)
129+
result8 = tree_to_list(root8)
130+
print(f"Input: {descriptions8}")
131+
print(f"Output: {result8}")
132+
print(f"Expected: [1, 2, None, None, 3, None, 4]")
133+
print_tree(root8)
134+
print()
135+
136+
137+
if __name__ == "__main__":
138+
run_tests()

0 commit comments

Comments
 (0)