Skip to content

Commit 838bd0f

Browse files
committed
add solution: construct-binary-tree-from-preorder-and-inorder-traversal
1 parent dbb43fc commit 838bd0f

File tree

1 file changed

+95
-0
lines changed
  • construct-binary-tree-from-preorder-and-inorder-traversal

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Definition for a binary tree node.
2+
# class TreeNode:
3+
# def __init__(self, val=0, left=None, right=None):
4+
# self.val = val
5+
# self.left = left
6+
# self.right = right
7+
class Solution:
8+
'''
9+
A. ์žฌ๊ท€ ํ’€์ด
10+
preorder์™€ inorder์˜ ๊ฐ๊ฐ์˜ ๋ฒ”์œ„๋ฅผ ์กฐ์ •ํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑ
11+
'''
12+
def buildTreeA(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
13+
def setTree(pre_left, pre_right, in_left, in_right):
14+
# ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: preorder ๋ฒ”์œ„๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
15+
if pre_left > pre_right:
16+
return None
17+
18+
val = preorder[pre_left] # preorder์˜ ํ˜„์žฌ ๋ฃจํŠธ ๋…ธ๋“œ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ
19+
mid = TreeNode(val) # ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ๋จผ์ € ์ƒ์„ฑ
20+
21+
mid_inorder = inorder_idx_map[val] # ๋ฃจํŠธ ๋…ธ๋“œ์˜ inorder ์ธ๋ฑ์Šค ๊ฐ€์ ธ์˜ค๊ธฐ
22+
left_size = mid_inorder - in_left # ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํฌ๊ธฐ ๊ณ„์‚ฐ
23+
24+
# ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ์ƒ์„ฑ: preorder์™€ inorder์˜ ๋ฒ”์œ„๋ฅผ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋กœ ์กฐ์ •
25+
mid.left = setTree(
26+
pre_left + 1, pre_left + left_size, in_left, mid_inorder - 1
27+
)
28+
29+
# ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ์ƒ์„ฑ: preorder์™€ inorder์˜ ๋ฒ”์œ„๋ฅผ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋กœ ์กฐ์ •
30+
mid.right = setTree(
31+
pre_left + left_size + 1, pre_right, mid_inorder + 1, in_right
32+
)
33+
34+
return mid # ํ˜„์žฌ ๋…ธ๋“œ ๋ฐ˜ํ™˜
35+
36+
# inorder๋ฅผ ๊ฐ’ -> ์ธ๋ฑ์Šค ๋งตํ•‘ํ•œ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ (O(n))
37+
inorder_idx_map = {value: idx for idx, value in enumerate(inorder)}
38+
39+
# ํŠธ๋ฆฌ ์ƒ์„ฑ ์‹œ์ž‘ (preorder์™€ inorder ์ „์ฒด ๋ฒ”์œ„ ์‚ฌ์šฉ)
40+
return setTree(0, len(preorder) - 1, 0, len(inorder) - 1)
41+
42+
43+
'''
44+
# B. ์žฌ๊ท€ ํ’€์ด + ๊ณต๊ฐ„ ์ตœ์ ํ™”
45+
# ๋ ˆํผ๋Ÿฐ์Šค ๋งํฌ์˜ ํ’€์ด 2: https://www.algodale.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
46+
# ํŠน์ง•: ์ˆœํšŒ ์‹œ๋งˆ๋‹ค ์ธ๋ฑ์Šค๋ฅผ ์ฐพ๋Š” ๊ณผ์ •์ด ์žˆ์Œ
47+
'''
48+
def buildTreeB(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
49+
# pre: ํ˜„์žฌ preorder์—์„œ ํ™•์ธํ•  ์ธ๋ฑ์Šค
50+
# start, end: inorder์—์„œ ์‚ฌ์šฉํ•  ์‹œ์ž‘/์ข…๋ฃŒ ๋ฒ”์œ„
51+
def setTree(pre, start, end):
52+
# ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: ๋ฒ”์œ„๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ํŠธ๋ฆฌ๋ฅผ ๋” ์ด์ƒ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
53+
if not (pre < len(preorder) and start <= end): # preorder์—์„œ ํ™•์ธํ•  ์ธ๋ฑ์Šค๊ฐ€ ๋ฒ”์œ„์—์„œ ๋‚˜๊ฐ, ํˆฌ ํฌ์ธํ„ฐ๊ฐ€ ๋งŒ๋‚จ
54+
return None
55+
56+
val = preorder[pre] # ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’
57+
root = inorder.index(val) # ํŠธ๋ฆฌ/์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ - SC: O(n)
58+
59+
left = setTree(pre + 1, start, root - 1)
60+
# inorder์—์„œ root๋…ธ๋“œ์˜ ์™ผ์ชฝ์€ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
61+
# pre์˜ ๋ณ€ํ™”: ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด +1 ์ด๋™
62+
63+
right = setTree(pre + 1 + root - start, root + 1, end)
64+
# inorder์—์„œ root๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ์€ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
65+
# pre์˜ ๋ณ€ํ™”: ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด +1 ์ด๋™ + (root - start) ๐Ÿ‘ˆ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํฌ๊ธฐ ๋งŒํผ ๋” ์ด๋™
66+
67+
return TreeNode(preorder[pre], left, right) # ํŠธ๋ฆฌ ๋…ธ๋“œ ์ƒ์„ฑ
68+
69+
# preorder ์ตœ์ดˆ ์ธ๋ฑ์Šค = ๋ฃจํŠธ ๋…ธ๋“œ(0), inorder์˜ ์ฒ˜์Œ(0)๊ณผ ๋(len(inorder) - 1) ์ธ๋ฑ์Šค
70+
return setTree(0, 0, len(inorder) - 1)
71+
72+
'''
73+
C. ์žฌ๊ท€ ํ’€์ด + ์‹œ๊ฐ„ ์ตœ์ ํ™”
74+
๋ ˆํผ๋Ÿฐ์Šค ๋งํฌ์˜ ํ’€์ด 3: https://www.algodale.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
75+
ํŠน์ง•: A์—์„œ preorder๋ฅผ ์ฐพ๋Š” O(n) ๊ณผ์ •์„ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜์—ฌ O(1)๋กœ ์ตœ์ ํ™”
76+
'''
77+
def buildTreeC(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
78+
# enumerate: ์ธ๋ฑ์Šค์™€ ๊ฐ’์„ ๋™์‹œ์— ๋ฐ˜ํ™˜
79+
# inorder๋ฅผ val -> idx๋กœ ๋งคํ•‘ํ•œ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ
80+
inorder_index_map = {val: idx for idx, val in enumerate(inorder)}
81+
# preorder๋ฅผ ์ˆœํšŒํ•˜๊ธฐ ์œ„ํ•œ iterator ๊ฐ์ฒด ์ƒ์„ฑ
82+
pre_iter = iter(preorder)
83+
84+
def setTree(start, end):
85+
if start > end: # ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: ๋ฒ”์œ„๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ํŠธ๋ฆฌ๋ฅผ ๋” ์ด์ƒ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
86+
return None
87+
88+
root_val = next(pre_iter) # ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’, ๋งค ์ˆœํšŒ๋งˆ๋‹ค ๋‹ค์Œ preorder ๋…ธ๋“œ(root)์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ด
89+
root = inorder_index_map[root_val] # ํŠธ๋ฆฌ/์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์ธ๋ฑ์Šค๋ฅผ O(1) ์‹œ๊ฐ„์œผ๋กœ ์ฐพ๊ธฐ
90+
91+
left = setTree(start, root - 1) # ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
92+
right = setTree(root + 1, end) # ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
93+
return TreeNode(root_val, left, right) # ํŠธ๋ฆฌ ๋…ธ๋“œ ์ƒ์„ฑ
94+
95+
return setTree(0, len(inorder) - 1) # inorder์˜ ์ฒ˜์Œ(0)๊ณผ ๋(len(inorder) - 1) ์ธ๋ฑ์Šค

0 commit comments

Comments
ย (0)