golang刷leetcode 重建二叉树

2022-08-02 19:05:24 浏览数 (1)

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]

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

返回如下的二叉树:

3

/

9 20

/

15 7

限制:

0 <= 节点个数 <= 5000

题目分析:

提到树相关的题目,我们首先想到递归,递归相关的问题,我们可以考虑借助栈来实现迭代解决。本题,有两种解法。

1,递归法:

前序遍历的形式总是

[ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]

即根节点总是前序遍历中的第一个节点。而中序遍历的形式总是

[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]

因此,我们可以从根节点切分开来,剩下的两部分分别对应左子树和右子树,递归解决即可

代码语言:javascript复制
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func buildTree(preorder []int, inorder []int) *TreeNode {
    if len(preorder)<1{
        return nil
    }
    root:=preorder[0]
    i:=0
    for i<len(inorder)&& inorder[i]!=root{
           i  
    }
    Left:=buildTree(preorder[1:i 1],inorder[:i])
    Right:=buildTree(preorder[i 1:],inorder[i 1:])
    return &TreeNode{
        Val:root,
        Left:Left,
        Right:Right,
    }
}

2,迭代法

前序遍历的过程是这样的:

(1)我们从根节点开始,一直遍历左孩子,直到没有左孩子为止。什么时候没有左孩子呢,我们遇到了中序遍历的第一个节点。

我们可以将上述过程,通过遍历前缀树,建树过程来实现。

(2)没有左孩子后,我们需要回溯,直到遇到右孩子,怎么做才能回溯呢?我们需要把(1)过程中遍历的节点入栈,然后通过出栈来回溯。

(3)出栈的过程是怎么样的呢?我们同步出栈和右移中序遍历的指针,中序遍历值和栈顶相等说明,没有遇到右孩子。遇到右孩子后,我们重复执行步骤(1)

代码语言:javascript复制
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func buildTree(preorder []int, inorder []int) *TreeNode {
    if len(preorder)<1{
        return nil
    }
    root:=&TreeNode{
        Val:preorder[0],
    }
    stack:=[]*TreeNode{root}
    index:=0
    for i:=1;i<len(preorder);i  {
        node:=stack[len(stack)-1]
        if node.Val!=inorder[index]{
            l:=&TreeNode{Val:preorder[i]}
            node.Left=l
            stack=append(stack,l)
        }else{
            for len(stack) != 0 && stack[len(stack)-1].Val == inorder[index] {
                node = stack[len(stack)-1]
                stack = stack[:len(stack)-1]
                index  
            }
            node.Right = &TreeNode{Val:preorder[i]}
            stack = append(stack, node.Right)

        }
    }
    return root
}

0 人点赞