Skip to content

Commit

Permalink
add solution: construct-binary-tree-from-preorder-and-inorder-traversal
Browse files Browse the repository at this point in the history
  • Loading branch information
dusunax committed Dec 20, 2024
1 parent dbb43fc commit 838bd0f
Showing 1 changed file with 95 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
'''
A. ์žฌ๊ท€ ํ’€์ด
preorder์™€ inorder์˜ ๊ฐ๊ฐ์˜ ๋ฒ”์œ„๋ฅผ ์กฐ์ •ํ•˜์—ฌ ํŠธ๋ฆฌ๋ฅผ ์ƒ์„ฑ
'''
def buildTreeA(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
def setTree(pre_left, pre_right, in_left, in_right):
# ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: preorder ๋ฒ”์œ„๊ฐ€ ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
if pre_left > pre_right:
return None

val = preorder[pre_left] # preorder์˜ ํ˜„์žฌ ๋ฃจํŠธ ๋…ธ๋“œ ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ธฐ
mid = TreeNode(val) # ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ๋จผ์ € ์ƒ์„ฑ

mid_inorder = inorder_idx_map[val] # ๋ฃจํŠธ ๋…ธ๋“œ์˜ inorder ์ธ๋ฑ์Šค ๊ฐ€์ ธ์˜ค๊ธฐ
left_size = mid_inorder - in_left # ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํฌ๊ธฐ ๊ณ„์‚ฐ

# ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ์ƒ์„ฑ: preorder์™€ inorder์˜ ๋ฒ”์œ„๋ฅผ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋กœ ์กฐ์ •
mid.left = setTree(
pre_left + 1, pre_left + left_size, in_left, mid_inorder - 1
)

# ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ ์ƒ์„ฑ: preorder์™€ inorder์˜ ๋ฒ”์œ„๋ฅผ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ๋กœ ์กฐ์ •
mid.right = setTree(
pre_left + left_size + 1, pre_right, mid_inorder + 1, in_right
)

return mid # ํ˜„์žฌ ๋…ธ๋“œ ๋ฐ˜ํ™˜

# inorder๋ฅผ ๊ฐ’ -> ์ธ๋ฑ์Šค ๋งตํ•‘ํ•œ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ (O(n))
inorder_idx_map = {value: idx for idx, value in enumerate(inorder)}

# ํŠธ๋ฆฌ ์ƒ์„ฑ ์‹œ์ž‘ (preorder์™€ inorder ์ „์ฒด ๋ฒ”์œ„ ์‚ฌ์šฉ)
return setTree(0, len(preorder) - 1, 0, len(inorder) - 1)


'''
# B. ์žฌ๊ท€ ํ’€์ด + ๊ณต๊ฐ„ ์ตœ์ ํ™”
# ๋ ˆํผ๋Ÿฐ์Šค ๋งํฌ์˜ ํ’€์ด 2: https://www.algodale.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
# ํŠน์ง•: ์ˆœํšŒ ์‹œ๋งˆ๋‹ค ์ธ๋ฑ์Šค๋ฅผ ์ฐพ๋Š” ๊ณผ์ •์ด ์žˆ์Œ
'''
def buildTreeB(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
# pre: ํ˜„์žฌ preorder์—์„œ ํ™•์ธํ•  ์ธ๋ฑ์Šค
# start, end: inorder์—์„œ ์‚ฌ์šฉํ•  ์‹œ์ž‘/์ข…๋ฃŒ ๋ฒ”์œ„
def setTree(pre, start, end):
# ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: ๋ฒ”์œ„๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ํŠธ๋ฆฌ๋ฅผ ๋” ์ด์ƒ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
if not (pre < len(preorder) and start <= end): # preorder์—์„œ ํ™•์ธํ•  ์ธ๋ฑ์Šค๊ฐ€ ๋ฒ”์œ„์—์„œ ๋‚˜๊ฐ, ํˆฌ ํฌ์ธํ„ฐ๊ฐ€ ๋งŒ๋‚จ
return None

val = preorder[pre] # ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’
root = inorder.index(val) # ํŠธ๋ฆฌ/์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ - SC: O(n)

left = setTree(pre + 1, start, root - 1)
# inorder์—์„œ root๋…ธ๋“œ์˜ ์™ผ์ชฝ์€ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
# pre์˜ ๋ณ€ํ™”: ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด +1 ์ด๋™

right = setTree(pre + 1 + root - start, root + 1, end)
# inorder์—์„œ root๋…ธ๋“œ์˜ ์˜ค๋ฅธ์ชฝ์€ ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
# pre์˜ ๋ณ€ํ™”: ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด +1 ์ด๋™ + (root - start) ๐Ÿ‘ˆ ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ์˜ ํฌ๊ธฐ ๋งŒํผ ๋” ์ด๋™

return TreeNode(preorder[pre], left, right) # ํŠธ๋ฆฌ ๋…ธ๋“œ ์ƒ์„ฑ

# preorder ์ตœ์ดˆ ์ธ๋ฑ์Šค = ๋ฃจํŠธ ๋…ธ๋“œ(0), inorder์˜ ์ฒ˜์Œ(0)๊ณผ ๋(len(inorder) - 1) ์ธ๋ฑ์Šค
return setTree(0, 0, len(inorder) - 1)

'''
C. ์žฌ๊ท€ ํ’€์ด + ์‹œ๊ฐ„ ์ตœ์ ํ™”
๋ ˆํผ๋Ÿฐ์Šค ๋งํฌ์˜ ํ’€์ด 3: https://www.algodale.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
ํŠน์ง•: A์—์„œ preorder๋ฅผ ์ฐพ๋Š” O(n) ๊ณผ์ •์„ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜์—ฌ O(1)๋กœ ์ตœ์ ํ™”
'''
def buildTreeC(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
# enumerate: ์ธ๋ฑ์Šค์™€ ๊ฐ’์„ ๋™์‹œ์— ๋ฐ˜ํ™˜
# inorder๋ฅผ val -> idx๋กœ ๋งคํ•‘ํ•œ ๋”•์…”๋„ˆ๋ฆฌ ์ƒ์„ฑ
inorder_index_map = {val: idx for idx, val in enumerate(inorder)}
# preorder๋ฅผ ์ˆœํšŒํ•˜๊ธฐ ์œ„ํ•œ iterator ๊ฐ์ฒด ์ƒ์„ฑ
pre_iter = iter(preorder)

def setTree(start, end):
if start > end: # ์žฌ๊ท€ ์ข…๋ฃŒ ์กฐ๊ฑด: ๋ฒ”์œ„๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ํŠธ๋ฆฌ๋ฅผ ๋” ์ด์ƒ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ
return None

root_val = next(pre_iter) # ํ˜„์žฌ ๋…ธ๋“œ์˜ ๊ฐ’, ๋งค ์ˆœํšŒ๋งˆ๋‹ค ๋‹ค์Œ preorder ๋…ธ๋“œ(root)์˜ ๊ฐ’์„ ๊ฐ€์ ธ์˜ด
root = inorder_index_map[root_val] # ํŠธ๋ฆฌ/์„œ๋ธŒํŠธ๋ฆฌ์˜ ๋ฃจํŠธ ๋…ธ๋“œ ์ธ๋ฑ์Šค๋ฅผ O(1) ์‹œ๊ฐ„์œผ๋กœ ์ฐพ๊ธฐ

left = setTree(start, root - 1) # ์™ผ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
right = setTree(root + 1, end) # ์˜ค๋ฅธ์ชฝ ์„œ๋ธŒํŠธ๋ฆฌ
return TreeNode(root_val, left, right) # ํŠธ๋ฆฌ ๋…ธ๋“œ ์ƒ์„ฑ

return setTree(0, len(inorder) - 1) # inorder์˜ ์ฒ˜์Œ(0)๊ณผ ๋(len(inorder) - 1) ์ธ๋ฑ์Šค

0 comments on commit 838bd0f

Please sign in to comment.