代码实现:给定一个中序遍历和后序遍历怎么构造出这颗树!(假定树中没有重复的数字)


因为没有规定是左小右大的树,所以我们随意画一颗数,来进行判断应该是满足题意的。

     3
/ \
2 4
/\ / \
1 6 5 7

中序遍历:.

后序遍历:.

我们知道后序遍历的最后一个肯定就是根了。然后在前序遍历中找到这个根,左边的就是左子树(记作subv1),右边的就是右子树(记作subv1)。在后序遍历中,前面的几个对应左子树的后序遍历(记作subv2),接下去的几个对应右子树的后序遍历(记作subv2),注意,右子树的后序遍历系系数因为3的不同位置所以要减一。

这样我们就可以分成两组的前序遍历和后序遍历的子数组了。然后递归调用返回,一个给根的左,一个给根的右。则有如下代码:

/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
{
if (inorder.size() == ) return NULL;
int rootval = postorder.back();
TreeNode *root = new TreeNode(rootval); vector<int> subv11, subv12, subv21, subv22;
bool flag = true; for (int i = ; i < inorder.size(); ++i)
{
if (inorder[i] == rootval) flag = false;
if (flag && inorder[i] != rootval)
{
subv11.push_back(inorder[i]);
subv21.push_back(postorder[i]);
}
else if (!flag && inorder[i] != rootval)
{
subv12.push_back(inorder[i]);
subv22.push_back(postorder[i - ]);
}
}
root -> left = buildTree(subv11, subv21);
root -> right = buildTree(subv12, subv22); return root;
}
};

如上,我是没次迭代的时候将数组分割成两部分,然后再对两部分分别递归求解。理论上应该是正确的。但是估计每次开辟新的vector存子数组用的空间一次一次递归用的空间太大了。以至于Memory Limit Exceeded


由上面的提示,我们知道,要达到好的效果那就不能一直开辟新的vector了,应该在原来的数组里操作,那么要达到和开辟新数组一样的效果就要用同时传入一些下标了。

中序遍历:3.

后序遍历:3.

同样的道理,首先我们要根据后序遍历的最后一个在中序遍历中分左右两部分,然后再确定后序遍历中相应部分的下标的起始位置。对每个数组我们传入两个下标参数,开始start和结束end下标。其中inorder的start记作is,end记作ie,postorder的start记作ps,end记作pe。

初始,中序遍历的开始为0,结束为inorder.size()-1.同理可以后序的也是类似。

每一次分割,中序遍历的126的开始为前一次开始is,结束为根节点3标号rootIndex-1,相应的后序遍历开始为前一次开始ps,因为长度要喝中序相同,所以结束为ps+(rootIndex-1-is)。

      中序遍历的的开始为根节点3标号rootIndex+1,结束为前一次的结束ie。我们可以确定结束为pe-1,因为长度相同,所以开始为pe-1-(ie-(rootIndex+1)).

那么就有代码:

/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *fun105(vector<int> &inorder, int is, int ie, vector<int> &postorder, int ps, int pe)
{
if (is > ie || ps > pe || ie - is != pe - ps) return NULL;
TreeNode *root = new TreeNode(postorder[pe]);
int rootIndex, rootval = root -> val;
for (int i = ; i <= ie; ++i)
{
if (inorder[i] == rootval)
rootIndex = i;
} root -> left = fun105(inorder, is, rootIndex - , postorder, ps, ps + (rootIndex--is));
root -> right = fun105(inorder, rootIndex + , ie, postorder, pe - - (ie-(rootIndex+)), pe - ); return root;
}
TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder)
{
if (inorder.size() == ) return NULL;
return fun105(inorder, , inorder.size() - , postorder, , postorder.size() - );
}
};

主要的难点就是下标的控制,特别是利用长度来控制后序遍历的结束下标和起始下标。

错误的尝试:本来没有用已知长度去求后序遍历的下标,而是直接根据rootInex的下标去找后序遍历的起始,后面发现因为rootIndex在第二次迭代的时候前面已经有一个之前的根了,所以和后序遍历的下标对应就会差1,所以是错误的。迫不得已,就用已知的长度相等和已知后序遍历的某些确定下标去求未知下标了。

leetcode[105] Construct Binary Tree from Inorder and Postorder Traversal的更多相关文章

  1. [Leetcode Week14]Construct Binary Tree from Inorder and Postorder Traversal

    Construct Binary Tree from Inorder and Postorder Traversal 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/pr ...

  2. Java for LeetCode 106 Construct Binary Tree from Inorder and Postorder Traversal

    Construct Binary Tree from Inorder and Postorder Traversal Total Accepted: 31041 Total Submissions: ...

  3. leetcode -day23 Construct Binary Tree from Inorder and Postorder Traversal &amp; Construct Binary Tree f

    1.  Construct Binary Tree from Inorder and Postorder Traversal Given inorder and postorder travers ...

  4. (二叉树 递归) leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  5. [LeetCode] 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  6. LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal (用中序和后序树遍历来建立二叉树)

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  7. C#解leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  8. LeetCode 106. Construct Binary Tree from Inorder and Postorder Traversal 由中序和后序遍历建立二叉树 C++

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

  9. 【leetcode】Construct Binary Tree from Inorder and Postorder Traversal

    Given inorder and postorder traversal of a tree, construct the binary tree. Note:You may assume that ...

随机推荐

  1. Windows下一个MySQL有些错误的解决方法

    1.无论是什么提示.我们有一个直接看错误日志.由于它描述了最具体描述错误日志. 于MySQL安装文件夹中找到 my.ini简介 看日志保存路径 2. 我的错误是[ERROR] Fatal error: ...

  2. (大数据工程师学习路径)第二步 Vim编辑器----Vim快速入门

    vim模式介绍 以下介绍内容来自维基百科Vim 从vi演生出来的Vim具有多种模式,这种独特的设计容易使初学者产生混淆.几乎所有的编辑器都会有插入和执行命令两种模式,并且大多数的编辑器使用了与Vim截 ...

  3. list-style-type 去除li 前面的标记(小黑点)

    list-style-type 设置标记的样式(或者隐藏标记) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//E ...

  4. MLAPP——概率机器学习知识汇总

    <机器学习>课程使用Kevin P. Murphy图书<Machine Learning A Probabilistic Perspective>本英语教材,本书从一个独特的数 ...

  5. poj 3400 Dropping the stones

    //next_permutation全阵列 # include <stdio.h> # include <algorithm> # include <string.h&g ...

  6. Unity3D 如何图形问题修正旋转模型已导入?

     如何纠正旋转模型被导入? 一些立体艺术资源包导出其模式,以便 Z 轴向上.Unity 大多数标准的脚本中假定的三维世界 Y 轴代表了.在 Unity 比改动脚本使其契合easy得多. Z 轴朝上 ...

  7. ABP之动态WebAPI

    ABP之动态WebAPI ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 ...

  8. jsmart 前结合案例

    前绑定jsmart这是一个不错的选择.之前通过经常使用的项目中的.最近涉及的领域的后端部.jsmart有些使用相对较少,主要是因为他想引用文件,我写的模板,在一个简单的项目,直接使用js界,很复杂的前 ...

  9. NYOJ 105 其余9个

    九的余数 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描写叙述 如今给你一个自然数n,它的位数小于等于一百万,如今你要做的就是求出这个数整除九之后的余数. 输入 第一行有一 ...

  10. HDU 1042 N! 參考代码

    HDU 1042 N! 题意:给定整数N(0 ≤ N ≤ 10000), 求 N! (题目链接) #include <iostream> using namespace std; //每一 ...