Skip to content

LeetCode-面试题07-重建二叉树

题目

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7
   
限制:
0 <= 节点个数 <= 5000

解题思路

方法1、递归

前序遍历的序列第一个位置就是root节点,后面分别是左子树和右子树,一开始无法知道哪些是左子树数字,哪些是右子树数字,但数字按照左——>右的顺序排列的。通过利用中序遍历序列可以得知,3的左边是左子树,3的右边是右子树。对于左子树,我们也能够获得其对应的前序和中序遍历,右子树同理。这样就将二叉树的建立转化为了一个递归问题:先在前序遍历确定根节点,然后确定中序中左子树开始和结束位置,以及右子树开始和结束位置,通过左子树前序和中序重建左子树,通过右子树前序和中序重建右子树,再向root添加左右子树的根节点,重建整个二叉树。

Java代码

java
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        if (preorder == null || preorder.length == 0) {
            return null;
        }
        Map<Integer, Integer> dict = new HashMap<>();
        // 建立中序map,快速获取位置
        int length = preorder.length - 1;
        for (int i = 0; i < inorder.length; i++) {
            dict.put(inorder[i], i);
        }
        TreeNode root = reconstrTree(preorder, 0, length, inorder, 0, length, dict);
        return root;
    }
    public TreeNode reconstrTree(int[] preorder, int postart, int poend, int[] inorder, int iostart, int ioend, Map<Integer, Integer> dict) {
        if (postart > poend) { // 二叉树没有节点
            return null;
        }
        int rootNode = preorder[postart]; // 对于前序序列,root节点就是第一个
        TreeNode root = new TreeNode(rootNode);
        if (postart == poend) { // 开始等于结束时,只有一个节点,就是root
            return root;
        } else {
            int rootIndex = dict.get(rootNode); // 获取root节点在中序序列的坐标
            int leftRange = rootIndex - iostart; // 得到左子树个数
            int rightRange = ioend - rootIndex; // 得到右子树个数
            // 传递左子树的前序和中序序列,建立左子树
            TreeNode leftTree = reconstrTree(preorder, postart + 1, postart + leftRange,inorder,iostart, rootIndex - 1, dict);
            // 传递右子树的前序和中序序列,建立右子树
            TreeNode rightTree = reconstrTree(preorder, poend - rightRange + 1, poend,inorder,rootIndex + 1, ioend, dict);
            root.left = leftTree;
            root.right = rightTree;
            return root;
        }
    }
}

Python代码

python
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
        def buildTree(self, preorder, inorder):
            """
            :type preorder: List[int]
            :type inorder: List[int]
            :rtype: TreeNode
            """
            self.dict1 = {}
            self.po = preorder
            polen = len(preorder)
            if (polen == 0):
                return
            for index, value in enumerate(inorder):
                self.dict1[value] = index
            return self.reconstrTree(0, 0, len(inorder) - 1)

        def reconstrTree(self, postart, instart, inend):
            if instart > inend: return
            root = TreeNode(self.po[postart])
            root_index = self.dict1[self.po[postart]]
            root.left = self.reconstrTree(postart + 1, instart, root_index - 1)
            root.right = self.reconstrTree(root_index - instart + postart + 1, root_index + 1, inend)
            return root