【LeetCode 二叉树专项】从中序与后序遍历序列构造二叉树(106)

1. 题目

定一棵树的中序遍历 inorder 与后序遍历 postorder 序列。请构造二叉树并返回其根节点。

1.1 示例

  • 示例

    1

    1

    1
    在这里插入图片描述

  • 输入: inorder = [9, 3, 15, 20, 7]postorder = [9, 15, 7, 20, 3]
  • 输出: [3, 9, 20, null, null, 15, 7]
  • 示例

    2

    2

    2

  • 输入: inorder = [-1]postorder = [-1]
  • 输出: [-1]

1.2 说明

1.3 限制

  • 1 <= preorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i], postorder[i] <= 3000
  • inorderpostorder 均无重复元素;
  • inorder 均出现在 postorder
  • inorder 保证为二叉树的中序遍历序列;
  • postorder 保证为二叉树的后序遍历序列。

2. 解法一(递归)

2.1 分析

此题和【LeetCode 二叉树专项】从前序与中序遍历序列构造二叉树(105)十分类似,解答的方法也相近。下面仅给出三张示意图:

  • 如何通过 postorder 序列找到根节点对应 val 域及其在 inorder 序列中的索引;
  • 如何通过根节点在 inorder 序列中的索引递归构建根节点的左子节点;
  • 如何通过根节点在 inorder 序列中的索引递归构建根节点的右子节点。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.2 实现

from collections import deque
from typing import List, Optional


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


class Solution:
    def _build_tree(self, inorder: List[int], in_start: int, in_stop: int,
                    postorder: List[int], post_start: int, post_stop) -> Optional[TreeNode]:
        if in_start > in_stop or post_start > post_stop:
            return
        index = inorder.index(postorder[post_stop])
        root = TreeNode(postorder[post_stop])
        root.left = self._build_tree(inorder, in_start, index - 1,
                                     postorder, post_start, post_start + index - 1 - in_start)
        root.right = self._build_tree(inorder, index + 1, in_stop,
                                      postorder, post_stop - in_stop + index, post_stop - 1)
        return root

    def build_tree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        return self._build_tree(inorder, 0, len(inorder) - 1, postorder, 0, len(inorder) - 1)


def main():
    inorder = [5, 2, 6, 4, 7, 1, 8, 3, 9]
    postorder = [5, 6, 7, 4, 2, 8, 9, 3, 1]
    sln = Solution()
    root = sln.build_tree(inorder, postorder)

    tree = []
    visiting = deque([root])
    while visiting:
        node = visiting.popleft()
        if node:
            tree.append(node.val)
            visiting.append(node.left)
            visiting.append(node.right)
        else:
            tree.append(None)

    while True:
        if not tree[-1]:
            tree.pop()
        else:
            break

    print(tree)  # [1, 2, 3, 5, 4, 8, 9, None, None, 6, 7]


if __name__ == '__main__':
    main()

2.3 复杂度

  • 时间复杂度:

    O

    (

    n

    )

    O(n)

    O(n),其中

    n

    n

    n 是树中的节点个数;

  • 空间复杂度:

    O

    (

    n

    )

    O(n)

    O(n)。我们需要使用

    O

    (

    n

    )

    O(n)

    O(n) 的空间存储哈希表,以及

    O

    (

    h

    )

    O(h)

    O(h)(其中

    h

    h

    h 是树的高度)的空间表示递归时栈空间。这里

    h

    <

    n

    h < n

    h<n,所以总空间复杂度为

    O

    (

    n

    )

    O(n)

    O(n)

3. 解法二(迭代)

作者: LeetCode-Solution

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>