105、从前序与中序遍历序列构造二叉树

  1. 105、 从前序与中序遍历序列构造二叉树
  2. 题解
    1. 1、二分递归构建
    2. 2、迭代法

105、 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

  • 前序遍历 preorder = [3,9,20,15,7]
  • 中序遍历 inorder = [9,3,15,20,7]
    返回如下的二叉树:
    3
   / \
  9  20
    /  \
   15   7

题解

1、二分递归构建

从前序遍历中找到根节点,在从中序遍历中找到左右子树区间

/**
 * 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) {
        return buildBTree(preorder,inorder,0,preorder.length - 1,0,inorder.length -1);
    }

    private TreeNode buildBTree(int[] preorder,int[] inorder,int pl,int pr,int il,int ir) {
        // 退出递归
        if (pl > pr || il > ir) {
            return null;
        }
        // 按照前序遍历 在中序遍历中 找到匹配的元素 将
        int rootVal = preorder[pl];
        int rootPos = 0;
        for (int i = il;i <= ir;i++) {
            if (inorder[i] == rootVal) {
                rootPos = i;
                break;
            }
        }
        TreeNode root = new TreeNode(rootVal);
        // rootPos = 1
        // 递归构建左右子树
        root.left = buildBTree(preorder,inorder,pl+1,pl+rootPos-il,il,rootPos);
        root.right = buildBTree(preorder,inorder,pl+rootPos-il+1,pr,rootPos+1,ir);
        // 返回根节点
        return root;
    }
}

2、迭代法

借用栈存储前序遍历的元素,后序遍历用一个index维护。
思路类似于二叉树的迭代法中序遍历!!!

/**
 * 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 || preorfer,length == 0) {
            return null;
        }
        // 创建根节点
        TreenNode root = new TreeNode(preorder[0]);
        // 辅助栈
        Stack<TreeNode> stack = new Stack<TreeNode>();
        // 存放根节点
        stack.push(root);
        // 中序遍历指针
        int inorderIndex = 0;
        for (int i = 1;i < preorder.length;i++) {
            // 获取前序遍历的元素,根节点右边分别为 左子树 右子树
            int preorderVal = preorder[i];
            // 获取当前根节点
            TreeNode node = stack.peek();
            // 中序遍历的当前元素不是根节点,说明存在左子树
            if (node.val != inorder[inorderIndex]) {
                // 构建左子树
                node.left = new TreeNode(preorderVal);
                // 左子树入栈
                stack.push(node.left);
            } else {
                // 没有左子树了,构建右子树
                while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) {
                    node.stack.pop();// 左子树根节点出栈
                    inorderIndex++;// 指针后移
                }
                // 构建右子树
                node.right = new TreeNode(preorderVal);
                // 右子树入栈
                stack.push(node.right);
            }
        }
        return root; // 返回根节点
    }
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

💰

Title:105、从前序与中序遍历序列构造二叉树

Count:596

Author:攀登

Created At:2020-07-26, 00:19:44

Updated At:2024-06-15, 15:52:32

Url:http://jiafeimao-gjf.github.io/2020/07/26/105%E3%80%81%E4%BB%8E%E5%89%8D%E5%BA%8F%E4%B8%8E%E4%B8%AD%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

×

Help us with donation