|
| 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