剑指offer第二版面试题6:重建二叉树(JAVA版)
题目:输入某二叉树的前序遍历和中序遍历的结果,请重新构造出该二叉树。假设输入的前序遍历和中序遍历的结果中不包含重复的数字。例如输入的前序遍历序列为{1,2,4,7,3,5,6,8}和中序遍历为{4,7,2,1,5,3,6,8},则重建出二叉树并输出它的头结点。
前序遍历:根节点--》左节点--》右节点
中序遍历:左节点--》根节点--》右节点
后序遍历:左节点--》右节点--》根节点
在二叉树的前序遍历序列中,第一个数字总是树的根节点的值。但在中序遍历中,根节点的值在序列的中间,左子树的结点的值位于根节点的值的左边,而右子树的结点的值位于根节点的右边。因此我们需要扫描中序遍历序列,才能找到根节点的值。
如图所示,前序遍历序列的第一个数字1就是根节点的值。扫描中序遍历序列,就能确定根节点的值的位置。根据中序遍历的特点,在根节点的值1前面3个数字都是左子树结点的值,位于1后面的数字都是右子树结点的值。
由于中序遍历序列中,有3个数字是左子树结点的值,因此左子树总共有3个左子结点。同样,在前序遍历的序列中,根节点后面的3个数字就是3个左子树结点的值,再后面的所有数字都是右子树结点的值。这样我们就在前序遍历和中序遍历两个序列中,分别找到了左右子树对应的子序列。

然后再根据左子树的前序遍历和中序遍历找出根节点和左右子树,可以使用递归来完成,每次得到根节点
用左子树来举例:
第二次:
前序:247
中序:472
根节点2,由中序可知没有右节点
第三次:
前序:47
中序:47
根节点:4
没有了左子树,7为4的右节点
代码如下:
/**
* 树节点
*/
class BinaryTreeNode {
int value;
BinaryTreeNode leftNode;
BinaryTreeNode rightNode;
public BinaryTreeNode(int value){
this.value=value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public BinaryTreeNode getLeftNode() {
return leftNode;
}
public void setLeftNode(BinaryTreeNode leftNode) {
this.leftNode = leftNode;
}
public BinaryTreeNode getRightNode() {
return rightNode;
}
public void setRightNode(BinaryTreeNode rightNode) {
this.rightNode = rightNode;
} } public class RebuildTree {
/**
* 根据前序遍历和中序遍历重建二叉树
* */
public static BinaryTreeNode rebuildTree(int[] preOrder, int[] inOrder){
if (preOrder == null || inOrder == null || preOrder.length == 0 || inOrder.length == 0 || preOrder.length != inOrder.length) {
return null;
}
//根节点
BinaryTreeNode root=new BinaryTreeNode(preOrder[0]);
root.setLeftNode(null);
root.setRightNode(null);
//左子树节点的个数
int leftNum=0;
for(int i=0;i<inOrder.length;i++){
if(inOrder[i]==root.getValue()){
break;
}else{
leftNum++;
}
}
//右子树节点的个数
int rightNum=inOrder.length-1-leftNum; //重建左子树
while(leftNum>0){
//用来存放左子树的前序遍历
int leftPreOrder[]=new int[leftNum];
//用来存放左子树的中序遍历
int leftInOrder[]=new int[leftNum];
//赋值给左子树每个节点值,把左子树再独立成一棵树
for(int i=0;i<leftNum;i++){
leftPreOrder[i]=preOrder[i+1];
leftInOrder[i]=inOrder[i];
}
BinaryTreeNode leftRoot=rebuildTree(leftPreOrder, leftInOrder);
root.setLeftNode(leftRoot);
}
//重建右子树
while(rightNum>0){
//右子树的前序遍历
int rightPreOrder[]=new int[rightNum];
//右子树的中序遍历
int rightInOrder[]=new int[rightNum];
//赋值 for(int i=0;i<rightNum;i++){
rightPreOrder[i]=preOrder[i+1+leftNum];
rightInOrder[i]=preOrder[i+1+leftNum];
}
BinaryTreeNode rightNode=rebuildTree(rightPreOrder, rightInOrder);
root.setRightNode(rightNode);
} return root;
} public static void main(String[] args) {
// 二叉树的先序序列
int[] preOrder = { 1, 2, 4, 7, 3, 5, 6, 8 };
// 二叉树的中序序列
int[] inOrder = { 4, 7, 2, 1, 5, 3, 8, 6 };
BinaryTreeNode root = rebuildTree(preOrder, inOrder);
}
}
剑指offer第二版面试题6:重建二叉树(JAVA版)的更多相关文章
- 《剑指offer》面试题6 重建二叉树 Java版
(由一个二叉树的前序和中序序列重建一颗二叉树) 书中方法:我们要重建一棵二叉树,就要不断地找到根节点和根节点的左子结点和右子节点.注意前序序列, 它的第一个元素就是二叉树的根节点,后面的元素分为它的左 ...
- 剑指offer第二版面试题7:二叉树的下一个节点(JAVA版本)
题目:给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 分析: 根据中序遍历的特点,要找到一个节点的下一个节点无非 ...
- 剑指offer第二版面试题4:替换空格(JAVA版)
题目:请实现一个函数,把字符串中的每个空格替换成“%20”.例如输入“We are happy”,则输出”We%20are%20happy”. 原因:在网络编程中,如果URL参数中含有特殊字符,如:空 ...
- 剑指offer第二版面试题5:从尾到头打印链表(JAVA版)
题目描述: 输入一个链表,从尾到头打印链表每个节点的值.返回新链表. import java.util.Stack; //定义链表结构 class ListNode { int value; List ...
- 剑指offer第二版面试题11:旋转数组的最小数字(JAVA版)
题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数 ...
- 剑指offer第二版面试题10:斐波那契数列(JAVA版)
题目:写一个函数,输入n,求斐波那契数列的第n项.斐波那契数列的定义如下: 1.效率很低效的解法,挑剔的面试官不会喜欢 使用递归实现: public class Fibonacci { public ...
- 剑指offer第二版面试题9:用两个队列实现栈(JAVA版)
题目:用两个队列实现栈. 分析:通过一系列的栈的压入和弹出操作来分析用队列模拟一个栈的过程,如图所示,我们先往栈内压入一个元素a.由于两个队列现在都是空,我们可以选择把a插入两个队列中的任一个.我们不 ...
- 剑指offer第二版面试题8:用两个栈实现队列(JAVA版)
题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deletedHead,分别完成在队列尾部插入节点和在队列头部删除节点的功能. 分析: 我们通过一个具体的例子来分析 ...
- 剑指offer第二版面试题3:二维数组中的查找(JAVA版)
题目: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 1 2 8 9 2 4 ...
随机推荐
- Python机器学习及分析工具:Scikit-learn篇
https://www.jianshu.com/p/e0844e7cdba5 https://sklearn.apachecn.org/docs/0.21.3/62.html 中文文档
- 用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验
目录 目录 前文列表 WTForms WTF 的基础使用 常用的字段类型 fieldsDateField fieldsIntegerField fieldsFloatField fieldsStrin ...
- python主要探索函数
在数据分析中,Python的主要探索函数 Python中主要用于书探索的是pandas(数据分析)和matplotlib(数据可视化).其中pandas提供了大量的数据探索的工具与数据相关的函数,这些 ...
- Spring 相关目录
Spring 相关目录 学习笔记 Spring 学习笔记 IoC 基础 Spring 学习笔记 Resource 资源 Spring 学习笔记 数据绑定,校验,BeanWrapper 与属性编辑器 源 ...
- leetcode.矩阵.73矩阵置零-Java
1. 具体题目 给定一个 m x n 的矩阵,如果一个元素为 0,则将其所在行和列的所有元素都设为 0.请使用原地算法. 示例 1: 输入: 输出:[ [ [1,1,1], [1,0,1], [ ...
- swat - 基于web的samba管理工具
总览 swat [ -s smb config file ] [ -a ] 描述 此程序是 samba 套件的一部分. swat 允许 samba 管理员通过web浏览器配置复杂的 smb.conf ...
- RemoTing 搭建简单实现
今天对C# Remoting进行了初步的学习,废话不说... RemotingModel: Talker.cs using System;using System.Collections.Generi ...
- ZOJ-3662 Math Magic 背包DP
这题不错,可惜我还是太弱了,没想到qwq. 看了网上大佬题解之后写的,对比了一下代码,好像我写的还是挺简洁的(逃,只是吞行比较多). 因为直接用lcm的值做下标会超时,所以我们观察发现可以组成lcm为 ...
- 【datatable】正在加载中的信息提示
datatable插件 DataTables is a plug-in for the jQuery Javascript library. It is a highly flexible tool, ...
- mongoose 数据库连接
1安装mongoose npm install mongoose 安装成功 2.打开数据库 mongod --path E:\mongo 成功 创建一个db.js var mongoose = req ...