【LeetCode】LCR 124. 推理二叉树

题目链接
题目描述:某二叉树的先序遍历结果记录于整数数组 preorder,它的中序遍历结果记录于整数数组 inorder。请根据 preorder 和 inorder 的提示构造出这棵二叉树并返回其根节点。

注意preorder 和 inorder 中均不含重复数字。
在这里插入图片描述
例子1:

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

输出: [3,9,20,null,null,15,7]

示例2:

输入: preorder = [-1], inorder = [-1]

输出: [-1]

数据范围:

1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列

理论知识:

先序:根左右
中序:左根右
后序:左右根
1、已知先序和中序能唯一确定一颗二叉树。
2、已知中序和后序能唯一确定一颗二叉树。
3、已知先序和后序 不能 唯一确定一颗二叉树。

思路:有前备知识我们很快能发现,先序主要作用是确定根,先序中的每个节点都会顺序的成为从上往下的子树的根节点;而通过先序中确定的根节点,在中序序列中,我们能够将二叉树进行初步划分左右子树,然后继续找先序中的根,继续划分左右子树,划分这个过程可以借助递归完成。这里面涉及到的问题点就是,不断找到根节点之后,在中序中找寻左右区间的问题。因此,为了直观一点,我们可以借助map来存储每个节点在数组中对应的顺序下标。这样,在找寻到一个根节点的时候,通过这个根节点所在中序中的位置确定下一次划分的区间。
代码:

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

 var (
    preIndex = 0 // 维护在递归时候获取先序的下一个节点
    inVal2IndexMap map[int]int // 维护中序序列中每个元素的对应的下标
 )
func deduceTree(preorder []int, inorder []int) *TreeNode {
    preIndex = 0 // 注意全局变量加载时机,载入这个文件进行多组输入时候,全局变量会一直未被重置
    // 标记每个中序数字所在的位置,方便通过先序递归时候划分边界
    inVal2IndexMap = make(map[int]int, len(inorder))
    for idx, val := range inorder {
        inVal2IndexMap[val] = idx
    }
    return reBuildTree(preorder, 0, len(inorder))
}

func reBuildTree(preorder []int, left, right int) *TreeNode{
    // 该子树没有子节点
    if left == right {
        return nil
    }
    // 构造当前的根节点,下标为preIndex
    root := &TreeNode{Val:preorder[preIndex]}
    // 找到先序这个根节点在中序中的位置
    inIndex := inVal2IndexMap[root.Val]
    preIndex++
    // 递归构造左子树
    root.Left = reBuildTree(preorder, left, inIndex)
    // 递归构造右子树 
    root.Right = reBuildTree(preorder, inIndex+1, right)
    
    return root
}

当然,上面借助了map,我们也可以不用借助额外的存储结构来实现程序。

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

func deduceTree(preorder []int, inorder []int) *TreeNode {
    for k := range inorder {
        if inorder[k] == preorder[0] {
            return &TreeNode{
                Val: preorder[0],
                Left: deduceTree(preorder[1:k+1], inorder[0:k]),
                Right: deduceTree(preorder[k+1:], inorder[k+1:]),
            }
        }
    }
    return nil
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

童话ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值