给定中序遍历inorder和后序遍历postorder, 请构造出二叉树.

算法思路: 设后序遍历为po, 中序遍历为io.

  • 首先取出po的最后一个节点作为根节点, 同时将这个节点入stn栈;
  • 随后比较io的最后一个节点和stn栈顶节点:
    • 如果不同则将此节点添加到栈顶节点的右侧并入stn栈, 同时从po中删除这个节点;

      • 此时的栈中保存了所有还未处理左子树的右侧根节点
      • 出现一次不同, 右侧子树的深度就增加1, 栈的深度就代表了当前右侧子树的深度
    • 如果相同, 先缓存栈顶节点, 分别删除io和栈顶元素:
      • 如果依旧相同(说明本层没有左子树), 则返回第2步;
      • 如果不同(说明有左子树), 则将po的最后一个节点添加到缓存节点p的左侧, 同时将左子树入栈并从po中删除此节点, 返回第2步;

代码:

 /**
* 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;
TreeNode *p;
TreeNode *root;
stack<TreeNode *> stn; root = new TreeNode(postorder.back());
stn.push(root);
postorder.pop_back(); while(true)
{
if(inorder.back() == stn.top()->val)
{
p = stn.top();
stn.pop();
inorder.pop_back();
if(inorder.size() == ) break;
if(stn.size() && inorder.back() == stn.top()->val)
continue;
p->left = new TreeNode(postorder.back());
postorder.pop_back();
stn.push(p->left);
}
else
{
p = new TreeNode(postorder.back());
postorder.pop_back();
stn.top()->right = p;
stn.push(p);
}
}
return root;
}
};

中序遍历的结果其实就是二叉树在垂直方向的投影.

注意到中序遍历的最后一个元素正好是二叉树的最右端的叶子, 而后序遍历最后才访问根节点, 也即右侧根节点都按由远到近的顺序排在最后, 所以程序第一次进入if的分支时, 树的右侧所有根节点已经构造完毕并入栈, 栈顶是最右侧的根节点.

并且此时中序遍历的结果并未删改, 我们从下到上进行左子叶的添加:

  • 如果中序遍历最后一个节点和栈上节点相同, 说明中序遍历的这个节点是根节点/右侧节点, 我们跳过它并从中序遍历和栈中删除它;
  • 但如果中序遍历的最后一个节点不是栈上节点, 这就说明此节点是当前父节点的左子叶, 我们添加它并删除它.

[LeetCode系列] 从中序遍历和后序遍历序列构造二叉树(迭代解法)的更多相关文章

  1. Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树

    Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树 Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序 ...

  2. LeetCode(106):从中序与后序遍历序列构造二叉树

    Medium! 题目描述: 根据一棵树的中序遍历与后序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 posto ...

  3. [leetcode]从中序与后序/前序遍历序列构造二叉树

    从中序与后序遍历序列构造二叉树 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 po ...

  4. Leetcode 106. 从中序与后序遍历序列构造二叉树

    题目链接 https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/descri ...

  5. Java实现 LeetCode 106 从中序与后序遍历序列构造二叉树

    106. 从中序与后序遍历序列构造二叉树 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序 ...

  6. leetcode 105 106 从前序与中序遍历序列构造二叉树 从中序与后序遍历序列构造二叉树

    题目: 105 根据一棵树的前序遍历与中序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中序遍历 inorder = ...

  7. leetcode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)

    目录 题目描述: 示例: 解法: 题目描述: 根据一棵树的中序遍历与后序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 示例: 给出 中序遍历 inorder = [9,3,15,20,7] ...

  8. LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)

    题目描述 根据一棵树的中序遍历与后序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9 ...

  9. Leetcode(106)-从中序与后序遍历序列构造二叉树

    根据一棵树的中序遍历与后序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 postorder = [9,15,7 ...

随机推荐

  1. Oracle HRMS APIs

    Oracle HRMS APIs..... Here I will be sharing all the Oracle HRMS APIs related articles. 参考地址: Oracle ...

  2. 转载:移动端+微信小程序实现,手机端滑动分页代码思路(ajax)

    //一般在PC上我们要分页都是通过上一页和下一页来实现的,手机通过当下滑到一定程度的时候自动加载下一页面//实现思路:首先加载部分数据,当下滑到某个元素可见的时候,如果还有数据,则新发送请求,然后追加 ...

  3. 如何用SPY++工具查看窗体的句柄

    我安装的是vs2012,先找到SPY++工具打开 打开方式: 方式1:通过路径(C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microso ...

  4. stimulsoft report工具—— 简单的多表连接打印报表例子

    一.用报表工具打印多个表格信息(包括学生表.教师表.班级表) 1.准备打印的数据(用sqlserver) 1)班级表

  5. SQL Server 调优系列基础篇 - 索引运算总结

    前言 上几篇文章我们介绍了如何查看查询计划.常用运算符的介绍.并行运算的方式,有兴趣的可以点击查看. 本篇将分析在SQL Server中,如何利用先有索引项进行查询性能优化,通过了解这些索引项的应用方 ...

  6. Tushare安装

    在python中安装tushare踩坑记录一下: 安装 lxml requests bs4 pandas 不然一直提示错误.

  7. The "Double-Checked Locking is Broken" Declaration

    双重检查锁定在延迟初始化的单例模式中见得比较多(单例模式实现方式很多,这里为说明双重检查锁定问题,只选取这一种方式),先来看一个版本: public class Singleton { private ...

  8. 关于edge detecte

    1.注意render Texture 双击render Texture ,要勾选 use viewport dimensions,否则出现边框和模型不合的情况 2.注意edge detecte 的状态 ...

  9. Oracle 常用的一些命令

    启动监听:lsnrctl start 查看监听:lsnrctl status 停止监听:lsnrctl stop 1.oracle 数据服务器包括:实例进程和数据库:    实例进程包括:memory ...

  10. (翻译)Angular 1.3中的验证器管道

    原文地址:VALIDATORS PIPELINE IN ANGULAR 1.3 我们知道在Angular中操作表单是很爽的.因为Angular本身的作用域模型,我们总能在相应的作用域中获取到表单当前的 ...