[剑指 Offer 第 2 版第 7 题] “重建二叉树”做题记录

[剑指 Offer 第 2 版第 7 题] “重建二叉树”做题记录

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

求解思路与关键

  • 画图是解决这一类问题的关键,千万不要犯懒,拿出纸和笔,动手操作一下,往往思路就很清晰了。
  • 用类似二叉树插入节点的方式建立二叉树,即使用递归函数,返回新创建二叉树根节点的方式,将新的二叉树的根结点挂接到原来的二叉树的左右结点中。
  • 前序遍历的第 1 个元素就是二叉树的根结点。根据这一点,不难写出递归函数的代码。注意这是以“输入的前序遍历和中序遍历的结果中都不含重复的数字”为前提的。

参考解答

参考解答1

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }
}

public class Solution {

    public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        TreeNode root = reConstructBinaryTree(pre, 0, pre.length - 1, in, 0, in.length - 1);
        return root;
    }

    /**
     * 根据前序遍历数组的 [preL, preR] 和 中序遍历数组的 [inL, inR] 重新组建二叉树
     *
     * @param pre  前序遍历数组
     * @param preL 前序遍历数组的区间左端点
     * @param preR 前序遍历数组的区间右端点
     * @param in   中序遍历数组
     * @param inL  中序遍历数组的区间左端点
     * @param inR  中序遍历数组的区间右端点
     * @return 构建的新二叉树的根结点
     */
    private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int[] in, int inL, int inR) {
        if (preL > preR || inL > inR) {
            return null;
        }
        // 构建的新二叉树的根结点一定是前序遍历数组的第 1 个元素
        TreeNode root = new TreeNode(pre[preL]);
        // 从中序遍历的左区间端点开始找,找到和前序遍历数组的第 1 个元素的值相等的节点
        int i = inL;
        while (in[i] != pre[preL] && i <= inR) {
            i++;
        }
        // 在中序遍历数组中遍历了几个元素: i - inL
        // 接下来就是递归调用,关键的地方在于找前序遍历数组和中序遍历数组对应的区间的端点
        root.left = reConstructBinaryTree(pre, preL + 1, preL + (i - inL), in, inL, i - 1);
        root.right = reConstructBinaryTree(pre, preL + (i - inL) + 1, preR, in, i + 1, inR);
        return root;
    }
}

猜你喜欢

转载自blog.csdn.net/lw_power/article/details/80748614