【剑指offer】面试题07 - 重建二叉树

面试题 7:重建二叉树

题目描述

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

链接:LeetCode 牛客网

例如

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

返回如下二叉树

   3
   / \
  9  20
    /  \
   15   7

解法一:递归构建左右子树

思路:

  1. 四个指针:
    • preorder_left 表示 preorder 的左边界,preorder_right 表示 preorder 的右边界
    • inorder_left 表示 inorder 的左边界,inorder_right 表示 inorder 的右边界
  2. 在 preorder 中找到 root 结点,并在 inorder 中定位到该 root 结点
  3. 一旦 root 结点被定位,该结点的左右子树便也确定
  4. 更新四个指针边界,递归构建左右子树

根据代码看图
在这里插入图片描述

TreeNode* myBuildTree(const vector<int>& preorder, const vector<int>& inorder, 
                      int preorder_left, int preorder_right, int inorder_left, int inorder_right) 
{
    
    
    if (preorder_left > preorder_right) 
        return nullptr;

    // 前序遍历中的第一个节点就是根节点
    int preorder_root_index = preorder_left;
    // 在中序遍历中定位根节点
    int inorder_root = index[preorder[preorder_root_index]];
    // 先把根节点建立出来
    TreeNode* root = new TreeNode(preorder[preorder_root_index]);
    // 得到左子树中的节点数目
    int size_left_subtree = inorder_root - inorder_left;
    // 递归地构造左子树,并连接到根节点
    // 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
    root->left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
    // 递归地构造右子树,并连接到根节点
    // 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
    root->right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
    return root;
}

TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
    
    
    int n = preorder.size();
    // 构造哈希映射,帮助我们快速定位根节点
    for (int i = 0; i < n; ++i) {
    
    
        index[inorder[i]] = i;
    }
    return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}

おすすめ

転載: blog.csdn.net/weixin_45437022/article/details/114268310