《剑指offer》- 重建二叉树

题目:

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

思路:

通过分析前序遍历和中序遍历的规律,前序遍历的第一个节点就是二叉树的根节点,中序遍历中,位于根节点前面的所有节点都位于左子树上,位于根节点后面的所有节点都位于右子树上面。通过这个规律,我们可以使用递归方法来重建二叉树。

代码实现:
  • 方式一
package com.neuedu.offer;

/**
 * 
 * @author 清水三千尺
 *
 */
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }

    @Override
    public String toString() {
        return "TreeNode [val=" + val + ", left=" + left + ", right=" + right + "]";
    }

}

public class Offer03 {
    // 參考答案
    public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        // 前序的第一个数是根节点
        TreeNode root = new TreeNode(pre[0]);

        int len = pre.length;
        if (len == 1) {
            root.left = null;
            root.right = null;

            return root;
        }

        // 找出中序中的根节点位置
        int rootVal = root.val;
        int i;
        for (i = 0; i < len; i++) {
            if (rootVal == in[i])
                break;
        }

        // 构建左子树
        if (i > 0) {
            int[] pr = new int[i];
            int[] ino = new int[i];

            for (int j = 0; j < i; j++) {
                pr[j] = pre[j + 1];
                ino[j] = in[j];
            }

            root.left = reConstructBinaryTree(pr, ino);
        } else {
            root.left = null;
        }

        // 构建右子树
        if (len - i - 1 > 0) {
            int[] pr = new int[len - i - 1];
            int[] ino = new int[len - i - 1];

            for (int j = i + 1; j < len; j++) {
                pr[j - i - 1] = pre[j];
                ino[j - i - 1] = in[j];
            }

            root.right = reConstructBinaryTree(pr, ino);
        } else {
            root.right = null;
        }

        return root;
    }

    // 测试答案
    public static void main(String[] args) {
        // 前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
        int[] arr1 = { 1, 2, 4, 7, 3, 5, 6, 8 };
        int[] arr2 = { 4, 7, 2, 1, 5, 3, 8, 6 };
        // 调用方法
        TreeNode reConstructBinaryTree = reConstructBinaryTree(arr1, arr2);
        System.out.println(reConstructBinaryTree.toString());
    }
}

  • 方式二
package com.neuedu.offer;

/**
 * 
 * @author 清水三千尺
 *
 */
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode(int x) {
        val = x;
    }

    @Override
    public String toString() {
        return "TreeNode [val=" + val + ", left=" + left + ", right=" + right + "]";
    }

}

public class Offer04 {
    // 參考答案
    public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {
        TreeNode root = reConstructBinaryTree(pre, 0, pre.length - 1, in, 0, in.length - 1);
        return root;
    }

    private static TreeNode reConstructBinaryTree(int[] pre, int startPre, int endPre, int[] in, int startIn,
            int endIn) {

        if (startPre > endPre || startIn > endIn)
            return null;
        TreeNode root = new TreeNode(pre[startPre]);

        for (int i = startIn; i <= endIn; i++)
            if (in[i] == pre[startPre]) {
                root.left = reConstructBinaryTree(pre, startPre + 1, startPre + i - startIn, in, startIn, i - 1);
                root.right = reConstructBinaryTree(pre, i - startIn + startPre + 1, endPre, in, i + 1, endIn);
                break;
            }

        return root;
    }

    // 测试答案
    public static void main(String[] args) {
        // 前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
        int[] arr1 = { 1, 2, 4, 7, 3, 5, 6, 8 };
        int[] arr2 = { 4, 7, 2, 1, 5, 3, 8, 6 };
        // 调用方法
        TreeNode reConstructBinaryTree = reConstructBinaryTree(arr1, arr2);
        System.out.println(reConstructBinaryTree.toString());
    }
}

运行截图:
《剑指offer》- 重建二叉树_第1张图片

你可能感兴趣的:(《剑指offer》- 重建二叉树)