首页 > 代码库 > 【LeetCode】106. Construct Binary Tree from Inorder and Postorder Traversal-通过中序和后续遍历还原二叉树

【LeetCode】106. Construct Binary Tree from Inorder and Postorder Traversal-通过中序和后续遍历还原二叉树

一、描述:

技术分享

二、思路:

二叉树的中序遍历和前序遍历或和后续遍历能唯一确定一节课二叉树,即2中还原方式都需要中序遍历才能完成;

设二叉树的前序遍历序列为{1, 2, 4, 5, 3, 6},中序遍历序列为{4,2,5,1, 3, 6}:(红色标记表示以还原节点!!!

  (1)-前序遍历的第一个节点是二叉树的根节点,{1, 2, 4, 5, 3, 6},对应中序中的位置是{4,2,5,1, 3, 6},所以中序序列中的 ‘1’ 之前的全部元素为左子树元素,‘1’之后的为右子树元素;

  (2)-左子树对应的前序中须遍历序列分别为{1, 2, 4},{4, 2, 5},执行(1),可得{2, 4,5},{4, 2, 5},即‘2’为左子树的根节点,{4}和{5}分别是以‘2’为根节点的左右子树(该例子中是左右叶子节点),执行(2),(3),最终左子树还原结果是:前序遍历{1, 2, 4, 5, 3, 6},中序遍历序列为{4,2,5,1, 3, 6};

  (3)-右子树对应的前序中序遍历序列分别为{3, 6},{3, 6},执行(1),可得{3, 6},{3, 6},即‘3’是右子树的根节点,{6}是以‘3’为根节点的右子树,左子树为空,故继续执行(3),得{6},{6},最终右子树的还原结果是:前序{3, 6},中序{3,6};

  故最终结果是左右子树全部还原(序列中的元素都为红色),还原结果是:前序遍历序列{1, 2, 4, 5, 3, 6},中序遍历序列{4,2,5,1, 3, 6},可以得出后续遍历结果序列是{4, 5, 2, 6, 3, 1}。

检测还原结果是否正确,可以通过剩余的一种遍历方式(后续遍历)的结果序列判断。

----------------------------------------------------分割线-----------------------------------------------------------------

关于本题:

1-从前序遍历的第一个元素开始,在中序遍历中找到该元素的位置(下标)rootIndex,中序序列中该位置之前的全部元素为左子树元素,之后的为右子树元素;

2-从分割线上过程可以看出,我们不管是要确定左子树元素和是右子树元素,都需要知道对应的元素个数,或者说是从rootIndex到最前位置或到最后位置的距离len(换句话只有知道了该位置到最前和最后的距离len,才能把左子树元素和右子树元素提出来,进行单独处理),在处理中只要知道了中序中rootIndex到起始位置的距离即可,到最后位置距离可以计算出;

3-若中序序列中根节点位置rootIndex大于中序序列起始位置,则说明该二叉树有左子树,则进行左子树递归;负责,当rootIndex不大于中序序列起始位置,且小于中序序列最后位置,说明到了还原右子树的时候了,则进行右子树递归;

4-当前序遍历序列中的元素全部被使用,则还原结束。

三、代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int len = preorder.length;
        if(len==0){
            return null;
        }
        return test(preorder, inorder, 0, len-1, 0, len-1);
    }
    
    public TreeNode test(int[] preorder, int[] inorder, int preStart, int preEnd, int inStart, int inEnd){
        TreeNode root = new TreeNode(preorder[preStart]); //还原根节点元素
        int rootIndex;
        for(rootIndex=inStart; rootIndex<inEnd;rootIndex++){
            if(preorder[preStart]==inorder[rootIndex]){
                break; //找到了根节点元素对应的下标位置
            }
        }
        int len = rootIndex-inStart;   //   左子树元素个数
        if(rootIndex>inStart){
            root.left = test(preorder, inorder, preStart+1, preStart+len, inStart, rootIndex-1);
        }
        if(rootIndex<inEnd){
            root.right = test(preorder, inorder, preStart+len+1, preEnd, rootIndex+1, inEnd);
        }
        return root;
    }
}

 

【LeetCode】106. Construct Binary Tree from Inorder and Postorder Traversal-通过中序和后续遍历还原二叉树