leetcode刷题日记——从前序与中序遍历序列构造二叉树

[ 题目描述 ]:
在这里插入图片描述
[ 思路 ]:

  • 递归构建,前序遍历是 [ 根节点,左孩子节点,右孩子节点 ],中序遍历是 [ 左孩子节点,根节点,右孩子节点]
  • 根据这一特性,可以知道,前序遍历中前面的节点是后面节点的,父亲或祖宗
  • 中序遍历中某个节点左边是他的左孩子们,右边是他的右孩子们
  • 由此我们对前序遍历的第一个节点开始构建,他一定是父节点,再将他在中序遍历中左边的节点和右边的节点划分出来,用于构建他的左右孩子
  • 以构建左孩子为例,求出左边孩子的个数n,由于前序遍历是 根左右 ,也就是说这些孩子一定在前序遍历的前 n+1个节点(第一个节点是父节点),将这 n 个前序遍历的节点和中序遍历的节点顺序列表进行新一轮递归
  • 运行如下
    在这里插入图片描述
# python代码
class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: Optional[TreeNode]
        """
        if not preorder or not inorder:
            return None
        root=TreeNode(preorder[0])
        val_index=inorder.index(preorder[0])
        left_inorder=inorder[0:val_index]
        right_inorder=inorder[val_index+1:]
        left_preoder=preorder[1:1+len(left_inorder)]
        right_preoder=preorder[1+len(left_inorder):]
        root.left=self.buildTree(left_preoder,left_inorder)
        root.right=self.buildTree(right_preoder,right_inorder)

        return root

[ 官方题解 ]:

  • 方法一:递归,基本同上
  • 方法二:迭代,依次枚举前序遍历中除了第一个节点以外的每个节点。如果 index 恰好指向栈顶节点,那么不断地弹出栈顶节点并向右移动 index,并将当前节点作为最后一个弹出的节点的右儿子;如果 index 和栈顶节点不同,则将当前节点作为栈顶节点的左儿子;
    • 无论是哪一种情况,最后都将当前的节点入栈。
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if not preorder:
            return None

        root = TreeNode(preorder[0])
        stack = [root]
        inorderIndex = 0
        for i in range(1, len(preorder)):
            preorderVal = preorder[i]
            node = stack[-1]
            if node.val != inorder[inorderIndex]:
                node.left = TreeNode(preorderVal)
                stack.append(node.left)
            else:
                while stack and stack[-1].val == inorder[inorderIndex]:
                    node = stack.pop()
                    inorderIndex += 1
                node.right = TreeNode(preorderVal)
                stack.append(node.right)

        return root
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值