"""
File: build_tree.py
Created Time: 2023-07-15
Author: Krahets (krahets@163.com)
"""

import sys, os.path as osp

sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__))))
from modules import *


def dfs(
    preorder: list[int],
    inorder: list[int],
    hmap: dict[int, int],
    i: int,
    l: int,
    r: int,
) -> TreeNode | None:
    """构建二叉树：分治"""
    # 子树区间为空时终止
    if r - l < 0:
        return None
    # 初始化根节点
    root = TreeNode(preorder[i])
    # 查询 m ，从而划分左右子树
    m = hmap[preorder[i]]
    # 子问题：构建左子树
    root.left = dfs(preorder, inorder, hmap, i + 1, l, m - 1)
    # 子问题：构建右子树
    root.right = dfs(preorder, inorder, hmap, i + 1 + m - l, m + 1, r)
    # 返回根节点
    return root


def build_tree(preorder: list[int], inorder: list[int]) -> TreeNode | None:
    """构建二叉树"""
    # 初始化哈希表，存储 inorder 元素到索引的映射
    hmap = {val: i for i, val in enumerate(inorder)}
    root = dfs(preorder, inorder, hmap, 0, 0, len(inorder) - 1)
    return root


"""Driver Code"""
if __name__ == "__main__":
    preorder = [3, 9, 2, 1, 7]
    inorder = [9, 3, 1, 2, 7]
    print(f"前序遍历 = {preorder}")
    print(f"中序遍历 = {inorder}")

    root = build_tree(preorder, inorder)
    print("构建的二叉树为：")
    print_tree(root)
