重建二叉树

前言:
 这道题是要根据前序和中序遍历的结果来构建二叉树,并返回根节点
 这里写下我的解题思路:
  前序遍历:根->左->右;中序遍历:左->根->右
  那么,每次前序遍历的首元素,在中序遍历的数组中的下标,就可以将中序数组分为左右两个子树;而中序分为两个子树,那么相应的前序也可以分为两个子树;
  这样,不断递归,一直分左右子树,最终就可以将二叉树构建完成。


下面贴代码

import java.util.Arrays;

public class ReConstructBinaryTree {

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

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

    // 重建二叉树
    public static TreeNode reConstructBinaryTree(int[] pre, int[] in) {

        // 当数组为 空 或只有一个元素的情况
        if (pre.length == 0){
            return null;
        }else if (pre.length == 1){
            return new TreeNode(pre[0]);
        }

        // 根节点
        TreeNode rootNode = new TreeNode(pre[0]);

        while (rootNode.left == null && rootNode.right == null){
            // 1. 查找根节点在 中序遍历数组in 中的下标位置
            int index = -1;
            for (int i = 0; i < in.length; i++) {
                if (in[i] == rootNode.val) {
                    index = i;
                    break;
                }
            }
            // 2. 拆分子树,并递归(Arrays.copyOfRange()方法的from和to参数,是>=from && <to)
            if (index == -1) {
                break;
            } else if ( index > 0 && index < pre.length-1){
                int[] preLeft = Arrays.copyOfRange(pre, 1, index+1);
                int[] preRight = Arrays.copyOfRange(pre, index + 1, pre.length);
                int[] inLeft = Arrays.copyOfRange(in, 0, index);
                int[] inRight = Arrays.copyOfRange(in, index + 1, in.length);
                rootNode.left = reConstructBinaryTree(preLeft, inLeft);
                rootNode.right = reConstructBinaryTree(preRight,inRight);
            } else if (index == 0){
                int[] preLeft = {};
                int[] preRight = Arrays.copyOfRange(pre, 1, pre.length);
                int[] inLeft = {};
                int[] inRight = Arrays.copyOfRange(in, 1, in.length);
                rootNode.left = reConstructBinaryTree(preLeft, inLeft);
                rootNode.right = reConstructBinaryTree(preRight,inRight);
            } else if (index == pre.length - 1){
                int[] preLeft = Arrays.copyOfRange(pre, 1, index+1);
                int[] preRight = {};
                int[] inLeft = Arrays.copyOfRange(in, 0, index);
                int[] inRight = {};
                rootNode.left = reConstructBinaryTree(preLeft, inLeft);
                rootNode.right = reConstructBinaryTree(preRight,inRight);
            }

        }

        return rootNode;
    }

    public static void main(String[] args) {
        TreeNode node = reConstructBinaryTree(new int[]{1, 2, 4, 7, 3, 5, 6, 8}, new int[]{4, 7, 2, 1, 5, 3, 8, 6});
        //System.out.println(reConstructBinaryTree(new int[]{1, 2, 4, 7, 3, 5, 6, 8}, new int[]{4, 7, 2, 1, 5, 3, 8, 6}));
        System.out.println("zzzz");
        System.out.println("emmmm");
    }

}

贴一点思路过程

顺带一点要注意:Arrays.copyOfRange()方法的from和to参数,是>=from && <to


  • 以上是我的思路写出的代码,但这些代码的编写花费了不少时间,其中的一些判断比较麻烦,花费了一些时间来DEBUG,才得到正确无误的结果
  • 希望能有更方便的解法,我这个思路没什么问题,就是实现免不了DEBUG
  • 后续有更优的解法,视情况返工这篇blog
原文地址:https://www.cnblogs.com/ihaokun/p/10753982.html