给定一棵树的中序遍历与后序遍历,依据此构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 = [9,3,15,20,7] 后序遍历 = [9,15,7,20,3]
返回如下的二叉树:
3 / \ 9 20 / \ 15 7
个人思路:
后序遍历序列的最后一个元素一定是该树的根节点,因而从此入手,在中序遍历序列中找到该元素,其左所有元素都是以该元素为根节点的左子树的节点,其右所有元素都是以该元素为根节点的右子树的节点,可在此将两边分为左子树和右子树的中序遍历子序列两个新的数组。同时,后序遍历序列中根节点之后的节点都是先把左子树节点遍历完毕才遍历右子树节点的,因此可以根据中序遍历序列中左子树节点的数量,找到所有属于左子树和右子树的元素,并分为两个新的后序遍历子序列数组。然后利用递归分别对左右子树的后序和中序序列进行处理,如果序列为空则返回null,如果序列只有一个值则可判断为叶子节点,返回当前节点。最终可得到一个完整的二叉树。
代码(JavaScript):
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {number[]} inorder * @param {number[]} postorder * @return {TreeNode} */ var buildTree = function(inorder, postorder) { var l=postorder.length; if(l==0){ return null; } var root=new TreeNode(postorder[l-1]); if(l==1){ return root; } var pos=0; for(pos=0;pos<l;pos++){ if(inorder[pos]==postorder[l-1]){ break; } } var Lpostorder=new Array(pos); var Linorder=new Array(pos); var Rpostorder=new Array(l-pos-1); var Rinorder=new Array(l-pos-1); for(var i=0;i<pos;i++){ Linorder[i]=inorder[i+1]; Lpostorder[i]=postorder[i]; } root.left=buildTree(Linorder,Lpostorder); for(var i=0;i<l-pos-1;i++){ Rinorder[i]=inorder[i+pos+1]; Rpostorder[i]=postorder[i+pos]; } root.right=buildTree(Rinorder,Rpostorder); return root; };