牛客网题目链接:重建二叉树

文章目录

  • 0 题目描述:
  • 1、题目分析
  • 2、代码
    • 2.1、java代码
    • 2.2 C++代码
  • 3、总结

0 题目描述:

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

1、题目分析

题目给出前序遍历和中序遍历,让重建二叉树。由前序遍历特性知前序遍历的第一个节点,肯定是根节点。那么找到了根节点,接下来找到左子树与右子树即可。由中序遍历的特性知中序遍历中,根节点位于中间某一个位置,它的左边是左子树节点,右边是右子树的节点。从而我们就找到了左子树的所有节点与右子树的所有节点以及根节点。然后我们让根节点左指针指向左子树的根节点,根节点右子树指针指向右子树的根节点。那么接下来的问题就是要求左子树的根节点与右子树的根节点,然后再让左子树的根节点指向它的左子树与右子树,右子树的根节点指向它的左子树与右子树…很明显,这是一个递归过程。

下面我们看以下图示,来理解找根节点,左子树与右子树的过程。

假设某一棵树如下:

它的前序遍历位:[1,2,4,7,3,5,6,8] 后序遍历:[4,7,2,1,5,3,8,6]

那么第一次找根节点与左右子树,如下图:

此时,可以得出如下我们要求的二叉树是如下样式:

以上我们只知道左子树和右子树包含哪些节点,并不知道左子树和右子树长什么样。

接下来我们再递归的求解左子树序列与右子树序列。,找到左子树的根节点与右子树的根节点。

递归求解左子树:

此时,可以得出如下二叉树的形式:

同理,此时对于左子树的根节点2,再对其递归求解它的左子树与右子树的二叉树,其中右子树位空不用求解直接指向null,左子树还有节点,那么利用左子树的节点的前序序列与中序序列,再次递归求解即可。

最终得出如下图所示的左子树二叉树:

递归求解右子树:

左子树递归求解完后,就递归求解右子树:

此时可以得到如下二叉树的形式:

同理,测试再对于右子树的节点3,再对其进行递归求它的左子树与右子树,最终得到右子树的二叉树为:

所以,最终的二叉树就是如下图:

2、代码

2.1、java代码

public class Solution {public TreeNode reConstructBinaryTree(int [] pre,int [] in) {if(pre.length-1==0 || in.length-1==0 || pre.length != in.length)return null;return reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);}public TreeNode reConstructBinaryTree(int[] pre,int preStart,int preEnd,int[] in,int inStart,int inEnd){int rootVal=pre[preStart];TreeNode root=new TreeNode(rootVal);//根节点root.left=root.right=null;if(preStart==preEnd || inStart==inEnd)return root;//如果只有一个数了则只有一个节点int inIndex=inStart;//代表中序遍历中的根节点的位置while(in[inIndex]!=rootVal && inIndex<=inEnd)inIndex++;//找到这个inIndex的位置int lnum=inIndex-inStart;//左子树节点的个数int rnum=inEnd-inIndex;//右子树节点的个数if(lnum>0){root.left=reConstructBinaryTree(pre,preStart+1,preStart+lnum,in,inStart,inIndex-1);}if(rnum>0){root.right=reConstructBinaryTree(pre,preStart+lnum+1,preEnd,in,inIndex+1,inEnd);}return root;}
}

注释:代码中inIndex代表中序遍历中根节点的位置,lnum代表左子树节点的个数,rnum代表右子树节点的个数。

2.2 C++代码

class Solution {public:TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {if(pre.size()==0 || vin.size()==0 || pre.size()!=vin.size())return nullptr;return reConstructBinaryTree(pre,0,pre.size()-1,vin,0,vin.size()-1);}TreeNode* reConstructBinaryTree(vector<int> pre, int preStart,int preEnd,vector<int> vin, int vinStart,int vinEnd){int rootVal=pre[preStart];TreeNode* root = new TreeNode(rootVal);//根节点root->left=nullptr;root->right=nullptr;if(preStart == preEnd || vinStart==vinEnd)return root;//如果只有一个数了则只有一个节点int vIndex = vinStart;//代表中序遍历中的根节点的位置while(rootVal != vin[vIndex] && vIndex <= vinEnd)vIndex++;//找到这个vIndex 的位置int lnum = vIndex-vinStart;//左子树节点的个数int rnum = vinEnd-vIndex;//右子树节点的个数int leftIndex = preStart+lnum;if(lnum>0){root->left = reConstructBinaryTree(pre,preStart+1,leftIndex,vin,vinStart,vIndex-1);}if(rnum>0){root->right = reConstructBinaryTree(pre,leftIndex+1,preEnd,vin,vIndex+1,vinEnd);}return root;}
};

注释:上面vIndex代表中序遍历中根节点的位置,lnum代表左子树的节点数目,rnum代表右子树的节点的数目。

3、总结

以上代码并不是最简洁的代码,但是目的是为了突出这种算法的实现过程。希望每个人都能很容易就理解这种递归的过程。

学习探讨加:
qq:1126137994
微信:liu1126137994

【剑指offer - C++/Java】4、重建二叉树相关推荐

  1. java 重建二叉树_【剑指offer】 Java实现重建二叉树

    /** * @Author: DaleyZou * @Description: 重建二叉树 * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树. * 假设输入的前序遍历和中序遍历的结果中都不 ...

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

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

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

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

  4. 剑指offer(04)重建二叉树

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

  5. 剑指offer(C++)-JZ7:重建二叉树(数据结构-树)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 给定节点数为 n 二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点. ...

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

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

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

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

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

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

  9. 剑指Offer(java答案)

    剑指Offer(java答案) 剑指Offerjava答案 3二维数组中的查找 4替换空格 5从尾到头打印链表 6重建二叉树 7用两个栈实现队列 8旋转数组的最小数字 9斐波那契数列 扩展1跳台阶 扩 ...

  10. 【剑指offer】Java版代码(完整版)

    参考链接 [剑指offer]Java版代码(完整版)

最新文章

  1. elasticsearch 分页_[Springboot实战系列]整合ElasticSearch实现数据模糊搜索
  2. python_day6.2
  3. 瞄准千亿个护市场,纸业龙头们下半场战役已经打响
  4. CentOS 5.5-yum安装配置LNMP
  5. 在WPF程序中使用多线程技术
  6. linux下面拷贝pdf却没法在windows下面打开
  7. 运行 java classnotfound_JAR运行出现ClassNotFoundException异常的解决办法
  8. LeetCode 2089. 找出数组排序后的目标下标
  9. java socket 抓包_linux下用socket的抓包程序
  10. SpringCloud 为什么需要使用配置中心
  11. charles捕获手机端请求数据
  12. f score matlab,机器学习中如何用F-score进行特征选择
  13. 计算机绘图相切,第九章计算机绘图基础.
  14. WPS2000系列之四图文混编(转)
  15. R语言——查看内置数据集
  16. 前端实现人员关系图谱
  17. iOS GPUImage研究六:为视频添加图片水印
  18. 开源Linux面板-1Panel
  19. java11协议,JDK11发布,Orale同时修改了oracle JDK11的授权协议 (转载)
  20. Android Studio强者之路-刘桂林-专题视频课程

热门文章

  1. java学习(95):线程的优先级
  2. oracle10g生成awr报告,awr报告生成位置.docx
  3. Linux: 两个USB摄像头的数据采集问题
  4. excel服务器2010网站,excel服务器2010
  5. mysql df_MySQL主从复制实战
  6. delphi dxBarManager 的dxBarEdit 输入问题
  7. asp.net mvc 自定义全局过滤器 验证用户是否登录
  8. C++语言第一课的学习
  9. jdbc建立数据库连接的helloword
  10. Entity Framework 数据库先行、模型先行、代码先行