zoukankan      html  css  js  c++  java
  • 重建二叉树

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


    下面贴代码

    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
  • 相关阅读:
    高性能反射初体验2
    高性能反射初体验1
    HTML解析原理
    QQ邮箱漂流瓶的"变化"~~
    javascript跟随滚动条滚动,onscroll事件的学习
    认识一下window.location.hash
    IE中替换a标签href属性的一个bug
    用css Sprites的时候IE6的一个小bug
    css中如何引入“非常” 字体
    [重温经典]ie6 不支持position:fix的解决方案
  • 原文地址:https://www.cnblogs.com/ihaokun/p/10753982.html
Copyright © 2011-2022 走看看