Leetcode 106:从中序与后序遍历序列构造二叉树(最详细的解法!!!)

根据一棵树的中序遍历与后序遍历构造二叉树。

注意:
你可以假设树中没有重复的元素。

例如,给出

中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]

返回如下的二叉树:

    3
   / \
  9  20
    /  \
   15   7

解题思路

实际上这个问题和之前Leetcode 105:从前序与中序遍历序列构造二叉树(最详细的解法!!!)是一样的。所以我们使用同样策略即可。

class Solution:
    def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        if inorder:
            ind = inorder.index(postorder.pop())
            root = TreeNode(inorder[ind])
            root.right = self.buildTree(inorder[ind+1:], postorder)
            root.left = self.buildTree(inorder[:ind], postorder)           
            return root

注意上面写法与之前写法的区别,也就是root.rightroot.left的前后位置问题。

同样的可以写出迭代版本。对于迭代的关键还是在于找根节点。我我们通过postorder知道3是整棵树的根节点,所以我们建立一个stack,然后将3加入到stack中。栈顶是我们每次要考虑的根节点,我们每次从后向前遍历postorder中的元素。我们首先考虑20应该放在哪?通过postorder我们知道20一定是root右子树的根节点,所以我们将9加入到root(3).right

stack: 3 20
    3
     \
     20

我们接着考虑7应该放在哪。我们通过postorder知道7一定是20右子树的根节点,所以我们将7放在20的右边。

stack: 3 20 7
    3
     \
     20
       \
        7

接着寻找7的左右孩子,我们通过inorder推断出7没有左右孩子。所以我们将7出栈。

stack: 3 20
    3
     \
     20
       \
        7

我们接着考虑15应该放在哪。我们通过postorder知道15一定是20左孩子的根节点。我们将15入栈。

stack: 3 20 15 
    3
     \
     20
    /  \
   15   7

通过inorder我们知道15没有左右孩子,所以我们将15出栈。我们发现20的左右子树已经填满了,所以我们将20也出栈。

stack: 3
    3
     \
     20
    /  \
   15   7

我们接着考虑9应该放在哪。我们发现3的左边还是空的,所以我们将9放到3的左边。同时将9入栈

stack: 3 9
    3
   / \
  9  20
    /  \
   15   7

接着就是具体实现上的细节。

class Solution:
    def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        if not inorder or not postorder:
            return 
        
        postorder.reverse()
        root = TreeNode(postorder[0])
        stack = [root]
        i = len(inorder) - 1

        for node in postorder[1:]:
            parent = stack[-1]
            
            if parent.val != inorder[i]:
                parent.right = TreeNode(node)
                stack.append(parent.right)     
            else:
                while stack and stack[-1].val == inorder[i]:
                    parent = stack.pop()
                    i -= 1
                parent.left = TreeNode(node)
                stack.append(parent.left)
                
        return root

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

你可能感兴趣的:(Problems,leetcode解题指南)