|
| 1 | +# https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ |
| 2 | + |
| 3 | +from typing import List, Optional |
| 4 | + |
| 5 | +# Definition for a binary tree node. |
| 6 | +class TreeNode: |
| 7 | + def __init__(self, val=0, left=None, right=None): |
| 8 | + self.val = val |
| 9 | + self.left = left |
| 10 | + self.right = right |
| 11 | + |
| 12 | +""" |
| 13 | +ํธ๋ฆฌ๋ฅผ ์ ์ผํ๊ฒ ๋ณต์ํ๊ธฐ ์ํด์๋ inorder๊ฐ ํ์ํ๋ค. inorder๋ left/right child๋ฅผ ๊ตฌ๋ถํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. |
| 14 | + - preorder + inorder: root๋ฅผ ๋จผ์ ์๊ณ , inorder๋ก ๊ตฌ์กฐ ๊ตฌ๋ถ |
| 15 | + - postorder + postorder: root๋ฅผ ๋์ค์ ์๊ณ , inorder๋ก ๊ตฌ์กฐ ๊ตฌ๋ถ |
| 16 | +preorder + postorder๋ผ๋ฉด, ๊ตฌ์กฐ๊ฐ ๋ค๋ฅธ ํธ๋ฆฌ๋ฅผ ๊ตฌ๋ถํ ์ ์๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. |
| 17 | +""" |
| 18 | + |
| 19 | +class Solution: |
| 20 | + def buildTree1(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: |
| 21 | + """ |
| 22 | + [Complexity] |
| 23 | + - TC: O(n^2) |
| 24 | + - SC: O(n^2) |
| 25 | + (* pop(0), index(), slicing์ด ๋ชจ๋ O(n)) |
| 26 | +
|
| 27 | + [Approach] |
| 28 | + preorder์ ๊ฒฝ์ฐ, root - left - right ์์๋ก ๋ฐฉ๋ฌธํ๋ฏ๋ก, root๋ฅผ ์ ์ผ ๋จผ์ ์ฐพ์ ์ ์๋ค. |
| 29 | + inorder์ ๊ฒฝ์ฐ, left - root - right ์์๋ก ๋ฐฉ๋ฌธํ๋ฏ๋ก, |
| 30 | + preorder์ ๋งค ๋จ๊ณ์์ ์ฐพ์ root์ ๋ํด left์ right subtree๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ ์ํ ์ ์๋ค. (root ์ ์ธ) |
| 31 | + - left subtree = inorder[:root_idx] |
| 32 | + - right subtree = inorder[root_idx + 1:] |
| 33 | + """ |
| 34 | + root = None |
| 35 | + |
| 36 | + if inorder: |
| 37 | + # preorder root |
| 38 | + root_idx = inorder.index(preorder.pop(0)) |
| 39 | + root = TreeNode(val=inorder[root_idx]) |
| 40 | + # preorder left |
| 41 | + root.left = self.buildTree(preorder, inorder[:root_idx]) |
| 42 | + # preorder right |
| 43 | + root.right = self.buildTree(preorder, inorder[root_idx + 1:]) |
| 44 | + |
| 45 | + return root |
| 46 | + |
| 47 | + def buildTree2(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: |
| 48 | + """ |
| 49 | + [Complexity] |
| 50 | + - TC: O(n^2) |
| 51 | + - SC: O(n^2) |
| 52 | + (* index(), slicing์ด ๋ชจ๋ O(n)) |
| 53 | +
|
| 54 | + [Approach] |
| 55 | + ์ด์ ์ฝ๋์์ pop(0)์ ๋๋ O(n)์ ์ค์ด๊ธฐ ์ํด, |
| 56 | + preorder.reverse() ํ pop()์ผ๋ก ๋ณ๊ฒฝํ ์ ์๋ค. |
| 57 | + """ |
| 58 | + preorder.reverse() |
| 59 | + |
| 60 | + def solve(preorder, inorder): |
| 61 | + if inorder: |
| 62 | + # preorder root |
| 63 | + root_idx = inorder.index(preorder.pop()) |
| 64 | + root = TreeNode(inorder[root_idx]) |
| 65 | + # preorder left |
| 66 | + root.left = solve(preorder, inorder[:root_idx]) |
| 67 | + # preorder right |
| 68 | + root.right = solve(preorder, inorder[root_idx + 1:]) |
| 69 | + |
| 70 | + return root |
| 71 | + |
| 72 | + return solve(preorder, inorder) |
| 73 | + |
| 74 | + def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: |
| 75 | + """ |
| 76 | + [Complexity] |
| 77 | + - TC: O(n) |
| 78 | + - SC: O(n) (call stack) |
| 79 | +
|
| 80 | + [Approach] |
| 81 | + ๋ณ๋ชฉ์ด์๋ index()์ slicing์ O(1)๋ก ์ต์ ํ ํ ์ ์๋ค. |
| 82 | + - index(): inorder์ index๋ฅผ dict๋ก ์บ์ฑ |
| 83 | + - slicing: start/end index๋ก ์ถ์ |
| 84 | + ์ด์ ๋๋ถ์ด preorder์ root๋ฅผ ๊ฐ๋ฆฌํค๋ index์ธ pre_idx๋ฅผ ์ฌ์ฉํ๋ฉด pop(0) ๋๋ pop()์ ๋์ฒดํ ์๋ ์๋ค. |
| 85 | + """ |
| 86 | + |
| 87 | + # instead of index() |
| 88 | + inorder_idx = {num: i for i, num in enumerate(inorder)} |
| 89 | + |
| 90 | + # preorder root (instead of pop()) |
| 91 | + pre_idx = 0 |
| 92 | + |
| 93 | + # instead of inorder[in_left:in_right] slicing |
| 94 | + def solve(in_left, in_right): |
| 95 | + nonlocal pre_idx |
| 96 | + |
| 97 | + # base condition |
| 98 | + if in_left >= in_right: |
| 99 | + return |
| 100 | + |
| 101 | + # preorder root |
| 102 | + root_val = preorder[pre_idx] |
| 103 | + root = TreeNode(root_val) |
| 104 | + |
| 105 | + # update indices |
| 106 | + root_idx = inorder_idx[root_val] |
| 107 | + pre_idx += 1 |
| 108 | + |
| 109 | + # recur |
| 110 | + root.left = solve(in_left, root_idx) |
| 111 | + root.right = solve(root_idx + 1, in_right) |
| 112 | + |
| 113 | + return root |
| 114 | + |
| 115 | + return solve(0, len(inorder)) |
0 commit comments