JS 剑指Offer(五) 二叉树的重建

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。


题目分析:已知二叉树的前序和中序遍历,根据前序遍历和中序遍历的规则,前序遍历的第一个节点一定是根节点,找到最上边的根结点之后,在中序遍历的结果中对应到它的位置,在左边的都是左子树,在右边的都是右子树。按照这个思路递归即可。

首先定义二叉树

1            function TreeNode(val){
2                this.val = val;
3                this.left = this.right = null
4            }

定义重建方法,传入两个数组,分别为preorder和inorder

           var buildTree = function(preorder,inorder){
               if(!inorder.length || !preorder.length){
                   return null
               }
               
               let root = {
                   val:preorder[0],
                   left:null,
                   right:null
               }
               let i = inorder.indexOf(preorder[0])
               console.log(i)
               //arrayObject.slice(start,end) 返回选中的元素 包上不包下 从0开始
               root.left = buildTree(preorder.slice(1,i+1),inorder.slice(0,i))
               //左子树的数量,小坑
               root.right = buildTree(preorder.slice(1+i),inorder.slice(i+1))
               
               return root;
               
           }

一开始的分析已经知道,前序遍历的第一个节点就是根节点,找到它的位置之后把左右子树第一次分开

然后通过递归依次找到左子树的根节点和右子树的根节点

这里有两个个非常非常重要的结论:1.中序遍历中只要找到根节点,左边都是左子树节点,右边都是右子树节点;2.因为树的节点是一定的,所以无论是左子树还是右子树,它们各自的前序遍历节点数量和中序遍历节点数量都相等。根据结论1,左子树节点为inorder.slice(0,i),右子树节点为inorder.slice(i+1),在前序遍历中找到对应的数量即可。

通过递归的方法,时间复杂度O(n)每个节点都需要有创建的过程和左右子树的重建过程,空间复杂度O(n)用于储存整棵树

posted @ 2020-04-06 22:00  前端攻城狮4536251  阅读(175)  评论(0)    收藏  举报