zoukankan      html  css  js  c++  java
  • 72 中序遍历和后序遍历树构造二叉树

    原题网址:https://www.lintcode.com/problem/construct-binary-tree-from-inorder-and-postorder-traversal/description

    描述

    根据中序遍历和后序遍历树构造二叉树

    你可以假设树中不存在相同数值的节点

    您在真实的面试中是否遇到过这个题?  

    样例

    给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2]

    返回如下的树:

      2

     /  

    1    3

    标签
    二叉树
     
     
    思路:要建立二叉树,首先要建立根节点,其次才是建立左右孩子并挂载。PS:建立链表是先确定前驱节点,再挂载。

    1.已知中序遍历和后序遍历,如何确定根节点?我们知道,后序遍历是左右根,所以后序遍历的最后一个节点是当前树的根节点。

    2.接下来是左右孩子,要借助中序遍历。中序遍历里,根节点左侧是左子树,右侧是右子树。先定位根节点(前提是树中不存在相同数值的节点),则左右子树的数量就可以确定了。根据左右子树的数量可以确定左右子树的中序遍历和后序遍历,递归构建并挂载左右子树即可。

    3.当中序遍历的起始索引大于结束索引时,说明二叉树已经建立完毕。

     

    AC代码:

    /**
     * Definition of TreeNode:
     * class TreeNode {
     * public:
     *     int val;
     *     TreeNode *left, *right;
     *     TreeNode(int val) {
     *         this->val = val;
     *         this->left = this->right = NULL;
     *     }
     * }
     */
    
    class Solution {
    public:
        /**
         * @param inorder: A list of integers that inorder traversal of a tree
         * @param postorder: A list of integers that postorder traversal of a tree
         * @return: Root of a tree
         */
        TreeNode * buildTree(vector<int> &inorder, vector<int> &postorder) {
            // write your code here
        int a=inorder.size();
        int b=postorder.size();
        if (a!=b||a==0||b==0)
        {
            return NULL;
        }
        return Build(inorder,postorder,0,a-1,0,b-1);
        
        }
        
        TreeNode * Build(vector<int> &inorder, vector<int> &postorder,int inst,int ined,int post,int poed)
    {
        if (inst>ined)
        {
            return NULL;
        }
        int i=inst;
        while(i<=ined&&inorder[i]!=postorder[poed])//找到中序遍历根节点所在位置;
        {
            i++;
        }
        TreeNode * root=new TreeNode(postorder[poed]);//根节点;
        root->left=Build(inorder,postorder,inst,i-1,post,post+i-1-inst);//左孩子;
        root->right=Build(inorder,postorder,i+1,ined,post+i-inst,poed-1);//右孩子;
        return root;
    }
    };

     

    其他方法:

    LintCode-72.中序遍历和后序遍历树构造二叉树

    Lintcode---中序遍历和后序遍历树构造二叉树

    以上两个链接是在中序遍历中定位根节点后,分别创建左子树的中序遍历、后序遍历数组,右子树的中序遍历、后序遍历数组,再递归。

     

    LintCode2016年8月8日算法比赛----中序遍历和后序遍历构造二叉树

    根据中序遍历和后序遍历树构造二叉树

     

     

     

    PS:最开始的递归函数只设置了起始和终止两个索引,因为我只注意到了左右子树在中序遍历和后序遍历中长度相等,但没注意到左右子树的起始、终止索引在中序遍历与后序遍历中是不一样的ORZ……也不知道当时怎么想的,明明画了图对照……

    Mark一下曾经的失败代码:

    TreeNode * build(vector<int> &inorder, vector<int> &postorder,int st,int ed)
    {
        if (st>ed)
        {
            return NULL;
        }
        int i=st;
        while(i<=ed&&inorder[i]!=postorder[ed])//找到中序遍历根节点所在位置;
        {
            i++;
        }
        TreeNode * root=new TreeNode(postorder[ed]);//根节点;
        root->left=build(inorder,postorder,st,i-1);//左孩子;
        root->right=build(inorder,postorder,i,ed-1);//右孩子,注意是从i开始,不是i+1;
        return root;
    }

     由于右孩子中序、后序区间索引没有一一对应,在编译器上运行【1,2,3】【1,3,2】时栈溢出。程序一直在递归build(inorder,postorder,1,1)……吐血。

     

     

  • 相关阅读:
    web.xml中<web-app>报错
    groovy初体验:groovy在java中的应用
    Mac安装JMeter时Unable to access jarfile ./ApacheJMeter.jar 解决方法
    intellij idea中解决java.lang.VerifyError: Expecting a stackmap frame at branch target的方法
    关于go get无法安装国内被墙软件解决办法
    Oracle 序列
    无锁并发框架Disruptor学习入门
    vsftp服务器部署
    FinalShell 推荐
    supperset (python 2.7.12 + mysql)记录
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/9271425.html
Copyright © 2011-2022 走看看