zoukankan      html  css  js  c++  java
  • 重建二叉树

    问题描述

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

    例如,给出

    前序遍历 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;
        }
  • 相关阅读:
    智能实验室-结构化存储浏览器(SSExplorer) 1.5.0.150
    智能实验室-杀马(Defendio) 3.1.0.681
    智能实验室-结构化存储浏览器(SSExplorer) 1.6.0.160
    IT餐馆—第八回 三十
    使用Silverlight Toolkit 绘制图表区域图和冒泡图
    IT餐馆—第十二回 软培
    IT餐馆—第四回 离职
    IT餐馆—第一回 前言
    IT餐馆—第十回 潜伏
    IT餐馆—第十三回 重构
  • 原文地址:https://www.cnblogs.com/xiaofeng-fu/p/13958788.html
Copyright © 2011-2022 走看看