重建二叉树

问题描述

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

例如,给出

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

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

返回如下的二叉树:

3

   / \

  9  20

    /  \

   15   7

限制: 0 <= 节点个数 <= 5000

解法一:

做这题之前我们先来看一下树的几种遍历顺序。

先序遍历:根节点→左子树→右子树。

中序遍历:左子树→根节点→右子树。

后续遍历:左子树→右子树→根节点。

其实也很好记,他是根据根节点遍历的顺序来定义的,比如先遍历根节点就是先序遍历,中间遍历根节点就是中序遍历,最后遍历根节点就是后续遍历,至于左子树和右子树哪个先遍历,记住一点,这3种遍历顺序右节点永远都不可能比左节点先遍历。

我们就以上面的示例数据来看下,前序遍历是[3,9,20,15,7],前序遍历先访问的是根节点,所以3就是根节点。中序遍历是[9,3,15,20,7],由于中序遍历是在左子树都遍历完的时候才遍历根节点,所有在中序遍历中3前面的都是3的左子树节点,3后面的都是3的右子树节点。也就是下面这样

 

 然后我们再使用同样的方式对左右子树继续划分,一直这样下去,直到不能再分为止。

解题思路步骤:

我们只需要使用3个指针即可。

preStart:他表示的是前序遍历开始的位置;

inStart,他表示的是中序遍历开始的位置;

inEnd:他表示的是中序遍历结束的位置;

我们主要是对中序遍历的数组进行拆解,下面就以下面的这棵树来画个图分析下

 

 

他的前序遍历是:[3,9,8,5,2,20,15,7]

他的中序遍历是:[5,8,9,2,3,15,20,7]

 

 

这里只要找到了前序遍历的结点在中序遍历的位置,我们就可以把中序遍历数组分解为两部分了。如果index是前序遍历的某个值在中序遍历数组中的索引,以index为根节点划分的话,那么中序遍历中

[0,index-1]就是根节点左子树的所有节点,

[index+1,inorder.length-1]就是根节点右子树的所有节点。

中序遍历好划分,那么前序遍历呢,如果是左子树:

preStart=index+1;

 

如果是右子树就稍微麻烦点,

preStart=preStart+(index-instart+1);

preStart是当前节点比如m先序遍历开始的位置,index-instart+1就是当前节点m左子树的数量加上当前节点的数量,所以preStart+(index-instart+1)就是当前节点m右子树前序遍历开始的位置,我们来看下完整代码:

 public TreeNode buildTree(int[] preorder, int[] inorder) {
        return helper(0, 0, inorder.length - 1, preorder, inorder);
    }

    private TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) {
        if (preStart > preorder.length - 1 || inStart > inorder.length - 1) {
            return null;
        }
        //创建结点,中节点
        TreeNode root = new TreeNode(preorder[preStart]);
        int index = 0;
        for (int i = inStart; i < inEnd; i++) {
            //查找中序遍历的位置,可以用map存储起来,然后get查找
            if (inorder[i] == root.val) {
                index = i;
                break;
            }
        }
        root.left = helper(preStart + 1, inStart, inStart - 1, preorder, inorder);
        root.right = helper(preStart + index - inStart + 1, index + 1, inEnd, preorder, inorder);
        return root;
    }

 

posted @ 2020-11-11 15:07  泉水姐姐。  阅读(80)  评论(0编辑  收藏  举报