๐ ๋ฌธ์ ๋ค์ ์ ๋ฆฌ
- preorder์ postorder ๋ฐฐ์ด์ด ์ฃผ์ด์ง ๋, ์ด ๋ฐฐ์ด์ ๊ธฐ๋ฐ์ผ๋ก ์ด์ง ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๋ฌธ์ ์ผ.
- ๋ ธ๋ ๊ฐ์ ์ค๋ณต๋์ง ์๋๋ค → ๋ฐ๋ผ์ ํญ์ ์ ์ผํ ํธ๋ฆฌ๋ฅผ ๋ง๋ค ์ ์์.
- preorder๋ (๋ฃจํธ → ์ผ์ชฝ → ์ค๋ฅธ์ชฝ) ์์์ด๊ณ ,
postorder๋ (์ผ์ชฝ → ์ค๋ฅธ์ชฝ → ๋ฃจํธ) ์์์ผ.
โ Java ์ฝ๋ ํ ์ค์ฉ ์ค๋ช
๋จผ์ ์ฝ๋ ์ ์ฒด๋ฅผ ๋ณด๊ณ , ํ ์ค์ฉ ๋ฏ์ด๋ณด์.
import java.util.HashMap;
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int x) { val = x; }
}
class Solution {
private HashMap<Integer, Integer> postorderIndexMap;
private int preorderIndex = 0;
public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
postorderIndexMap = new HashMap<>();
for (int i = 0; i < postorder.length; i++) {
postorderIndexMap.put(postorder[i], i);
}
return buildTree(preorder, postorder, 0, postorder.length - 1);
}
private TreeNode buildTree(int[] preorder, int[] postorder, int left, int right) {
if (left > right || preorderIndex >= preorder.length) {
return null;
}
TreeNode root = new TreeNode(preorder[preorderIndex++]);
if (left == right) {
return root;
}
int leftSubtreeRootVal = preorder[preorderIndex];
int leftSubtreeIndex = postorderIndexMap.get(leftSubtreeRootVal);
root.left = buildTree(preorder, postorder, left, leftSubtreeIndex);
root.right = buildTree(preorder, postorder, leftSubtreeIndex + 1, right - 1);
return root;
}
}
1๏ธโฃ TreeNode ํด๋์ค ์ ์
class TreeNode {
int val;
TreeNode left, right;
TreeNode(int x) { val = x; }
}
- ์ด์ง ํธ๋ฆฌ๋ฅผ ๋ํ๋ด๋ ๋ ธ๋ ํด๋์ค๋ฅผ ์ ์.
- val: ํ์ฌ ๋ ธ๋์ ๊ฐ.
- left: ์ผ์ชฝ ์์ ๋ ธ๋.
- right: ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋.
- ์์ฑ์๋ฅผ ์ด์ฉํด ๊ฐ์ ์ด๊ธฐํํ๋ค.
2๏ธโฃ Solution ํด๋์ค์ ํ๋
class Solution {
private HashMap<Integer, Integer> postorderIndexMap;
private int preorderIndex = 0;
- postorderIndexMap: ํ์ ์ํ์์ ๋
ธ๋ ๊ฐ๊ณผ ์ธ๋ฑ์ค๋ฅผ ๋งคํํด์ ์ ์ฅํ๋ HashMap.
- ์๋ฅผ ๋ค์ด postorder = [4, 5, 2, 6, 7, 3, 1]์ด๋ฉด {4=0, 5=1, 2=2, 6=3, 7=4, 3=5, 1=6}์ด ์ ์ฅ๋จ.
- ์ด๋ ๊ฒ ํ๋ฉด O(1)์ ์๊ฐ๋ณต์ก๋๋ก ์ธ๋ฑ์ค๋ฅผ ์ฐพ์ ์ ์์.
- preorderIndex: ์ ์ ์ํ ๋ฐฐ์ด์์ ํ์ฌ ํ์ ์ค์ธ ์ธ๋ฑ์ค.
- ์ฒ์์๋ 0, ์ฆ preorder[0]๋ถํฐ ํ์์ ์์ํจ.
3๏ธโฃ constructFromPrePost ํจ์
public TreeNode constructFromPrePost(int[] preorder, int[] postorder) {
postorderIndexMap = new HashMap<>();
for (int i = 0; i < postorder.length; i++) {
postorderIndexMap.put(postorder[i], i);
}
return buildTree(preorder, postorder, 0, postorder.length - 1);
}
๐น ํ๋ ์ผ
- postorderIndexMap์ ์ฑ์ด๋ค → ํ์ ์ํ ๋ฐฐ์ด์ ๊ฐ ๊ฐ๊ณผ ์ธ๋ฑ์ค๋ฅผ ์ ์ฅ.
- buildTree(preorder, postorder, 0, postorder.length - 1) ํธ์ถํ์ฌ ํธ๋ฆฌ๋ฅผ ๋ง๋ ๋ค.
4๏ธโฃ buildTree ํจ์ (ํธ๋ฆฌ ์ฌ๊ท ์์ฑ)
private TreeNode buildTree(int[] preorder, int[] postorder, int left, int right) {
preorder์ postorder๋ฅผ ์ฌ์ฉํด, left๋ถํฐ right ๋ฒ์์ ์๋ธํธ๋ฆฌ๋ฅผ ๋ง๋๋ ์ฌ๊ท ํจ์.
5๏ธโฃ ๊ธฐ์ ์กฐ๊ฑด (Base Case)
if (left > right || preorderIndex >= preorder.length) {
return null;
}
- left > right: ํ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ฉด null ๋ฐํ.
- preorderIndex >= preorder.length: preorder๋ฅผ ๋ค ํ์ํ์ผ๋ฉด null ๋ฐํ.
6๏ธโฃ ํ์ฌ ๋ ธ๋ ์์ฑ
TreeNode root = new TreeNode(preorder[preorderIndex++]);
- preorder[preorderIndex] ๊ฐ์ ์ฌ์ฉํ์ฌ ํ์ฌ ๋ ธ๋ ์์ฑ.
- preorderIndex++: ๋ค์ ํธ์ถ์์ preorder์ ๋ค์ ๊ฐ ์ฌ์ฉ.
7๏ธโฃ ๋จ์ผ ๋ ธ๋์ธ ๊ฒฝ์ฐ ๋ฐ๋ก ๋ฐํ
if (left == right) {
return root;
}
์๋ธํธ๋ฆฌ์ ๋ ์ด์ ์์์ด ์์ผ๋ฉด ํ์ฌ ๋ ธ๋ ๋ฐํ.
8๏ธโฃ ์ผ์ชฝ ์๋ธํธ๋ฆฌ ๋ฃจํธ ์ฐพ๊ธฐ
int leftSubtreeRootVal = preorder[preorderIndex];
int leftSubtreeIndex = postorderIndexMap.get(leftSubtreeRootVal);
- preorder[preorderIndex]: ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ๋ฃจํธ ๊ฐ.
- postorderIndexMap.get(leftSubtreeRootVal): ํ์ ์ํ์์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ์ ๋ง์ง๋ง ๋ ธ๋ ์์น ์ฐพ๊ธฐ.
9๏ธโฃ ์ผ์ชฝ ์๋ธํธ๋ฆฌ ์ฌ๊ท ํธ์ถ
root.left = buildTree(preorder, postorder, left, leftSubtreeIndex);
left ~ leftSubtreeIndex ๋ฒ์์์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ ์์ฑ
๐ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ ์ฌ๊ท ํธ์ถ
root.right = buildTree(preorder, postorder, leftSubtreeIndex + 1, right - 1);
leftSubtreeIndex + 1 ~ right-1 ๋ฒ์์์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ ์์ฑ.
> python
# 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:
def constructFromPrePost(self, preorder: List[int], postorder: List[int]) -> Optional[TreeNode]:
postorder_index_map = { val : idx for idx, val in enumerate(postorder)}
self.preorder_index = 0
def buildTree(left: int, right : int) -> Optional[TreeNode] :
if left > right or self.preorder_index >= len(preorder) :
return None
root = TreeNode(preorder[self.preorder_index])
self.preorder_index += 1
if left == right :
return root
left_subtree_root_val = preorder[self.preorder_index]
left_subtree_index = postorder_index_map[left_subtree_root_val]
root.left = buildTree(left, left_subtree_index)
root.right = buildTree(left_subtree_index+1, right-1)
return root
return buildTree(0, len(postorder) - 1)