剑指offer——面试题6:重建二叉树

一个小知识点:已知二叉树的中序遍历和前序遍历(或后序遍历)结果则可以确定该二叉树;但是通过二叉树的前序遍历和后序遍历结果无法确定该二叉树!!!

Solution1:

根据书中算法写的c++版本的代码,不知为何,未能AC…
下面代码有bug,但找了好久木找到。。。。
2018年3月15日更新:在师兄的帮助下,bug找到了。。。
bug在

/*** Definition for binary tree* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {
public:struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { //pre vin中分别是前序和后序遍历的结果int n_pre = pre.size(),n_vin = vin.size();if(n_pre == 0 || n_vin == 0)return NULL;return BuildTree(0,n_pre-1,0,n_vin-1,pre,vin);}struct TreeNode* BuildTree(int prestart,int preend,int vinstart,int vinend,vector<int> &pre_vec,vector<int> &vin_vec){//前序遍历序列的第一个数字是根结点的值int rootValue = pre_vec[prestart];struct TreeNode* root = new TreeNode(rootValue);root->left = root->right = NULL;if(prestart == preend){if(vinstart == vinend && pre_vec[prestart] == vin_vec[vinstart])return root;elsestd::cout<<"Invalid input."<<std::endl;}//在中序遍历中找到根结点的值int rootInvin = vinstart;while(rootInvin <= vinend && vin_vec[rootInvin] != rootValue)++rootInvin;if(rootInvin == vinend && vin_vec[rootInvin]!=rootValue)std::cout<<"Invalid input."<<std::endl;//int leftlength=rootInvin-prestart;总是犯这种傻逼错误,而瞎耽误时间int leftlength=rootInvin-vinstart;int leftpreend=prestart+leftlength;if(leftlength>0){//构建左子树,若取等号则左子树为空,没必要构建root->left = BuildTree(prestart+1,leftpreend,vinstart,rootInvin-1,pre_vec,vin_vec);}if(leftlength+prestart<preend){//构建右子树,若取等号则右子树为空,没必要构建root->right = BuildTree(leftpreend+1,preend,rootInvin+1,vinend,pre_vec,vin_vec);}return root;}
};

Solution2:c++中排名第一的答案

理论上浪费了空间,但是实现起来简单了很多。。。

/*** Definition for binary tree* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/
class Solution {public:struct TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> in) {int inlen=in.size();if(inlen==0)return NULL;vector<int> left_pre,right_pre,left_in,right_in;//创建根节点,根节点肯定是前序遍历的第一个数struct TreeNode* head=new TreeNode(pre[0]);//找到中序遍历根节点所在位置,存放于变量gen中int gen=0;for(int i=0;i<inlen;i++){if (in[i]==pre[0]){gen=i;break;}}//对于中序遍历,根节点左边的节点位于二叉树的左边,根节点右边的节点位于二叉树的右边//利用上述这点,对二叉树节点进行归并for(int i=0;i<gen;i++){left_in.push_back(in[i]);left_pre.push_back(pre[i+1]);//前序第一个为根节点}for(int i=gen+1;i<inlen;i++){right_in.push_back(in[i]);right_pre.push_back(pre[i]);}//和shell排序的思想类似,取出前序和中序遍历根节点左边和右边的子树//递归,再对其进行上述所有步骤,即再区分子树的左、右子子数,直到叶节点head->left=reConstructBinaryTree(left_pre,left_in);head->right=reConstructBinaryTree(right_pre,right_in);return head;}};

20180830重做

通过中序+前序/后序遍历结果重建二叉树的写法基本差不多,牢记!!!

/*** 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* reConstructBinaryTree(vector<int> pre,vector<int> vin) {if (!pre.size() || !vin.size()) return NULL;TreeNode* root;root = my_build(pre, vin);return root;}TreeNode* my_build(vector<int> pre, vector<int> vin) {if (!pre.size()) return NULL;//为空返回空指针,即叶子结点TreeNode* root = new TreeNode(pre[0]);//建立根结点vector<int> left_pre, right_pre, left_in, right_in;//找到根结点的值在中序遍历中的位置int root_val_mark = 0;for (int i = 0; i < vin.size(); i++) {if (vin[i] == pre[0]) {root_val_mark = i;break;}}//构造左子树序列for (int i = 0; i < root_val_mark; i++) {left_pre.push_back(pre[i+1]);left_in.push_back(vin[i]);}//构造右子树序列for (int i = root_val_mark + 1; i < pre.size(); i++) {right_pre.push_back(pre[i]);right_in.push_back(vin[i]);}//递归走起!root->left = my_build(left_pre, left_in);root->right = my_build(right_pre, right_in);return root;}
};

剑指offer——面试题6:重建二叉树相关推荐

  1. 剑指offer面试题6 重建二叉树(java)

    注:(1)java中树的构建 (2)构建子树时可以直接利用Arrays.copyOfRange(preorder, from, to),这个方法是左开右闭的 1 package com.xsf.Sor ...

  2. 剑指offer面试题[6]-重建二叉树

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...

  3. 剑指Offer - 面试题7. 重建二叉树(递归)

    1. 题目 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如,给出前序遍历 preorder = [3,9,20,15,7] 中序遍 ...

  4. 剑指offer面试题07. 重建二叉树(递归)(切片)

    题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 思路 详见链接 代码 #class TreeNode: # def __ini ...

  5. 剑指offer——面试题58:二叉树的下一个结点

    剑指offer--面试题58:二叉树的下一个结点 这个题要认真分析一下... Solution1: 自己想出来的破算法 /* struct TreeLinkNode {int val;struct T ...

  6. 剑指offer——面试题39:二叉树的深度

    剑指offer--面试题39:二叉树的深度 20180906整理 Solution1: 再本题中树的定义:若二叉树只有一个根节点,则此二叉树的深度为1. 迭代法,哈哈哈 /* struct TreeN ...

  7. 【重点】剑指offer——面试题25:二叉树中和为某一值的路径

    剑指offer--面试题25:二叉树中和为某一值的路径 参考网址:https://www.nowcoder.com/profile/5488508/codeBookDetail?submissionI ...

  8. 【递归】剑指offer——面试题19:二叉树的镜像

    剑指offer--面试题19:二叉树的镜像 Solution1: 递归解法,牢记! 根结点为空的情况容易漏,注意! /* struct TreeNode {int val;struct TreeNod ...

  9. 剑指offer_面试题6_重建二叉树(分解步骤,逐个击破)

    题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字. 例如:输入前序遍历 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7 ...

  10. 剑指offer第7题 重建二叉树

    前言 该系列文章为本人刷leetcode的记录,主要旨在分享刷题的思路及算法解析(尽可能的一题多解),另方便自己日后查阅回顾.代码的实现语言是python和go. 想进大厂免不了刷题,一起加油吧,小伙 ...

最新文章

  1. Jenkins在Mac平台安裝
  2. 【c++】10. memset()、【strcpy_s()、memcpy_s()】、【strcpy(),memcpy()】
  3. datagrid出现相同两组数据_数据分析之统计学
  4. 【Linux】一步一步学Linux——make命令(259)
  5. 【转载】我为啥不想用Python
  6. python冷知识_python冷知识
  7. 如何使得账户密码永不过期
  8. html语言简单,简单的html语言计算器
  9. mapreduce介绍_MapReduce:简单介绍
  10. Qt实用快捷键(较全面)
  11. sz 命令错误输入成xz,粗心导致的小事故
  12. 超越存储,历久弥新!新华三发布入门级存储产品
  13. 某LINUX下,从快捷方式的目录运行程序,参数就是快捷方式的名
  14. NetLogo学习笔记1 —— 初步认识
  15. 为什么定义补码等于反码加一,知其所以然
  16. 《72个促成交易的经典技巧:…
  17. python3的fft_Python fft.fft方法代码示例
  18. Matlab制作GUI
  19. Unity 射击游戏的准星位置
  20. Scratch运动指令积木块篇

热门文章

  1. 弗拉门戈-吉普赛婚礼-保利剧院
  2. 机器视觉——鱼眼相机成像模型
  3. 数据结构笔记(一)-- 概念
  4. 最小二乘法拟合多项式原理以及c++实现
  5. win7 计算机打不开搜狗,搜狗输入法无法使用,教你win7系统电脑搜狗输入法无法使用的解决方法...
  6. php感悟1500,《与美同行》读后感1500字
  7. phpmyadmin创建/导入/导出mysql数据库教程_PhpMyAdmin创建/导入/导出MySQL数据库教程[图文]...
  8. tiny core linux 7.1,极度简约 最小 Linux 发行版 Tiny Core Linux 7.1 发布
  9. jeesite如何已生成数据的数据源_jeesite 多数据源配置
  10. 华为新系统鸿蒙效果,19款华为手机内测新系统,流畅度比肩苹果iOS,优先体验鸿蒙OS...