leetcode-根据中序遍历和后序遍历重构二叉树 思路与代码

问题描述

问题链接:https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

leetcode,medium
106:Construct Binary Tree from Inorder and Postorder Traversal

给定树的中序遍历和后序遍历,请构建原来的二叉树。假设不存在重复的元素。

Given inorder and postorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.

问题分析

举个栗子:
inorder = [9,3,15,20,7]
postorder = [9,15,7,20,3]

首先要搞清楚二叉树的后序遍历和中序遍历的特点,可以参考二叉树的前序、中序、后序、层序遍历方式,然后具体思路如下:

  1. 后序遍历的数组的最后1个元素一定是根节点元素,由此确定根节点元素;
  2. 由于所有元素都不重复,可以找出根节点元素在中序遍历数组中的位置index,那么中序遍历数组中,index之前的元素(一共有index个,注意数组下标从0开始的)一定都是左子树的节点,且是左子树的中序遍历结果,index之后的元素一定都是右子树的节点,且是右子树的中序遍历结果;
  3. 后序遍历数组中,从第1个元素开始往后一共index个元素是左子树的后序遍历结果,从位置为index+1的元素直到倒数第2个元素都是右子树的后序遍历结果;
  4. 在步骤2、3中,得到左子树的后序遍历和中序遍历,以及右子树的后序遍历和中序遍历,那么使用递归即可。

问题解法

结合上面思路,直接看代码。

def construct_bt_inorder_postorder_traversal(inorder, postorder):
    def build2(inorder, postorder):
        if not inorder:
            return None
        elif len(inorder) == 1:
            return TreeNode(inorder[0])
        else:
            postorder_root_val = postorder[-1]
            root = TreeNode(postorder_root_val)
            for i in range(len(inorder)):
                if postorder_root_val == inorder[i]:
                    inorder_root_index = i
                    break
            root.left = build1(inorder[:inorder_root_index], postorder[:inorder_root_index])
            root.right = build1(inorder[inorder_root_index + 1:], postorder[inorder_root_index:-1])
        return root


    return build2(inorder, postorder)

测试代码如下:

if __name__ == "__main__":
    inorder = [9, 3, 15, 20, 7]
    postorder = [9, 15, 7, 20, 3]

    res = construct_bt_inorder_postorder_traversal(inorder, postorder)

    print(layer_traverse(res))

输出结果:[3, 9, 20, 15, 7]

哈哈,上面的layer_traverse实现的是二叉树的层序遍历,我是为了打印方便,哈哈很容易实现,可以参考二叉树的前序、中序、后序、层序遍历方式中的层序遍历或者找我要。

你可能感兴趣的:(LeetCode,算法,数据结构)