๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
TIL

[์ฝ”ํ…Œ์—ฐ์Šต] 889. Construct Binary Tree from Preorder and Postorder Traversal

by ํฌ๋ผ00 2025. 2. 23.

https://leetcode.com/problems/construct-binary-tree-from-preorder-and-postorder-traversal/description/?envType=daily-question&envId=2025-02-23

 

๐Ÿ“Œ ๋ฌธ์ œ ๋‹ค์‹œ ์ •๋ฆฌ

  • 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);
}

 

 

๐Ÿ”น ํ•˜๋Š” ์ผ

  1. postorderIndexMap์„ ์ฑ„์šด๋‹ค → ํ›„์œ„ ์ˆœํšŒ ๋ฐฐ์—ด์˜ ๊ฐ ๊ฐ’๊ณผ ์ธ๋ฑ์Šค๋ฅผ ์ €์žฅ.
  2. 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)