剑指 Offer 07. 重建二叉树解题思路

文章目录

  • 题目
  • 解题思路
    • 优化

题目

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

示例 1:

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]

示例 2:

Input: preorder = [-1], inorder = [-1]
Output: [-1]

限制:

0 <= 节点个数 <= 5000

解题思路

先自己写笨蛋代码,是错的。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public TreeNode BuildTree(int[] preorder, int[] inorder) 
    {
        FindHead(preorder,inorder,0);
        return 
    }
    //root为节点下标
    public void FindHead(int[] preorder, int[] inorder,int root)
    {
        if(root == inorder.Length)return;//直到根节点的最后一个值
        //先序遍历第一个值为根节点
        TreeNode currentRoot = new TreeNode(preorder[root]);
        //中序遍历中 根节点左边值为左子树
        for(int i = root;i<inorder.Length;i++)
        {
            if(currentRoot.val == inorder[i])
            {
                t.left = new TreeNode(inorder[i-1]);
            }
        }
        //先序遍历中 左子树右边为根节点
        for(int i = root;i<preorder.Length;i++)
        {
            if(t.left.val == preorder[i])
            {
                t.right = new TreeNode(preorder[i+1]);
                FindRoot(preorder,inorder,i+1);//重复
            }
        }
    }
}

优化

看一看别人家的代码

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     public int val;
 *     public TreeNode left;
 *     public TreeNode right;
 *     public TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    Dictionary<int,int> dic;
    int[] preorder;
    public TreeNode BuildTree(int[] preorder, int[] inorder) 
    {
        if(preorder.Length == 0) return null;
        this.preorder=preorder;
        dic = new Dictionary<int,int>();
        for(int i=0;i<inorder.Length;i++)
        {
            dic[inorder[i]]=i;
        }
        return BuildTreeInternal(0,preorder.Length-1,0);
    }
     TreeNode BuildTreeInternal(int pl, int pr, int il)
    {
        if(pl>pr) return null;
        var root = new TreeNode(preorder[pl]);
        int i=dic[root.val];
        var leftChildEnd = pl+i-il;
        root.left=BuildTreeInternal(pl+1,leftChildEnd,il);
        root.right=BuildTreeInternal(leftChildEnd+1,pr,i+1);
        return root;
    }
}

递归思路:在先序遍历中头结点是根节点,在中序找到该节点,也就找到了左右子树。然后在先序中该节点的后一个节点其实就是左子树的根节点,并且通过中序中的左子树计算得到先序中左子树的尾结点,这样的话先序中尾结点的后一个节点就是当前右子树根节点。最后就是按照上面方式一直递归找左右子树的根节点即可重建二叉树。

作者:尽力而为
链接:https://leetcode.cn/problems/zhong-jian-er-cha-shu-lcof/solutions/2202337/zhong-jian-er-cha-shu-di-gui-by-jin-li-e-8qyi/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
学会了就是我的了。

你可能感兴趣的:(LeetCode,算法,数据结构)