Featured image of post 106. 从中序与后序遍历序列构造二叉树

106. 从中序与后序遍历序列构造二叉树

题目描述

给定两个整数数组 inorderpostorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例 1:

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

示例 2:

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

提示:

  • 1 <= inorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i], postorder[i] <= 3000
  • inorder 和 postorder 都由 不同 的值组成
  • postorder 中每一个值都在 inorder 中
  • inorder 保证是树的中序遍历
  • postorder 保证是树的后序遍历

解法一:递归

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
func buildTree(inorder []int, postorder []int) *TreeNode {
    vToIdx := make(map[int]int)
    for idx, v := range inorder {
        vToIdx[v] = idx
    }

    var build func(iL, iR, pL, pR int) *TreeNode
    build = func(iL, iR, pL, pR int) *TreeNode {
        if iL > iR {
            return nil
        }
        root := &TreeNode{Val: postorder[pR]}
        // root 的左子树的节点的数目
        lCnt := vToIdx[root.Val] - iL
        root.Left = build(iL, vToIdx[root.Val]-1, pL, pL+lCnt-1)
        root.Right = build(vToIdx[root.Val]+1, iR, pL+lCnt, pR-1)
        return root
    }
    return build(0, len(inorder)-1, 0, len(postorder)-1)
}

官方题解如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
func buildTree(inorder []int, postorder []int) *TreeNode {
    idxMap := map[int]int{}
    for i, v := range inorder {
        idxMap[v] = i
    }
    var build func(int, int) *TreeNode
    build = func(inorderLeft, inorderRight int) *TreeNode {
        // 无剩余节点
        if inorderLeft > inorderRight {
            return nil
        }

        // 后序遍历的末尾元素即为当前子树的根节点
        val := postorder[len(postorder)-1]
        postorder = postorder[:len(postorder)-1]
        root := &TreeNode{Val: val}

        // 根据 val 在中序遍历的位置,将中序遍历划分成左右两颗子树
        // 由于我们每次都从后序遍历的末尾取元素,所以要先遍历右子树再遍历左子树
        inorderRootIndex := idxMap[val]
        // important! 一定要先构造右子树
        root.Right = build(inorderRootIndex+1, inorderRight)
        root.Left = build(inorderLeft, inorderRootIndex-1)
        return root
    }
    return build(0, len(inorder)-1)
}
Licensed under CC BY-NC-SA 4.0
最后更新于 2023/05/06 13:52:02
comments powered by Disqus
Built with Hugo
主题 StackJimmy 设计