重建二叉树:

题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
 
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x){
val = x;
}
}
 import java.util.HashMap;

 /**
* 先序数组: 1,2,4,7,3,5,6,8 中序数组:4,7,2,1,5,3,8,6
* 思路:1.先序数组中最左边的值就是树的头节点值,记为和,并且用h生成
* 头节点,记为head。然后在中序数组中找到h,假设位置为i。那么在
* 中序数组中,i左边的数组就是头节点左子树的中序数组,假设长度
* 为L,则左子树的先序数组就是先序数组中h往右长度也为L的数组
* 例如:二叉树头节点的值为1,在数组中找到1的位置,1的左边数组为
* 4,7,2 是头节点左子树的中序数组,长度为3; 先序数组中1的右边长度
* 也是3的数组为:2,4,7 , 也就是左子树的先序数组。
* 2. 用左子树的先序和中序数组,递归整个过程建立左子树,返回的头节点记为left。
* 3. i右边的数组就是头结点右子树的中序数组,假设长度为r。先序数组中右侧等长
* 部分就是头节点右子树的先序数组。
* 例如:中序数组中1的右边数组为:5,3,8,6,长度为4; 先序数组右侧等长的部分为:
* 3,5,6,8,他们分别是头节点右子树的中序和先序数组。
* 4. 用右子树的先序和中序数组,递归整个过程建立右子树,返回的节点记为right。
* 5. 把head的左孩子和有孩子分别设为left和right,返回head,过程结束。
*
* 如果二叉树的节点数为N,在中序数组中找到位置i的过程可以用哈希表来实现,这样整个
* 过程时间复杂度为O(n)。
*/
public class Solution { public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre == null || in == null){
return null;
}
HashMap<Integer, Integer> map = new HashMap<>();
for(int i=0; i < in.length; i++){
map.put(in[i],i);
}
return preIn(pre, 0, pre.length -1 , in, 0, in.length -1, map);
} /**
* 递归函数
* @param p 前序数组
* @param pi 前序数组的初始下标
* @param pj 前序数组的结束下标
* @param n 中序数组
* @param ni 中序数组的初始下标
* @param nj 中序数组的结束下标
* @param map 中序值和位置的map集合
* @return
*/
public TreeNode preIn(int[] p, int pi, int pj, int[] n, int ni, int nj, HashMap<Integer,Integer> map){ if(pi > pj){
return null;
}
//头节点
TreeNode head = new TreeNode(p[pi]);
//头节点在中序的位置
int index = map.get(p[pi]);
head.left = preIn(p, pi + 1, pi + index - ni, n, ni, index -1, map);
head.right = preIn(p, pi + index - ni + 1, pj, n, index + 1, nj, map);
return head;
} }

剑指offer_(4)的更多相关文章

  1. 剑指offer_(17)

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) public class Solution17 { /*思路:参考剑指offer 1.首先设置标志 ...

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

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

  3. 剑指offer_面试题11 数值的整数次方_考察代码的完整性

    测试通过代码: package t0825; public class Power { public static void main(String[] args){ System.out.print ...

  4. 剑指offer_快速查找递增二维数组中是否存在目标

    [编程题]二维数组中的查找 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数     ...

  5. 牛客_剑指offer_重建二叉树,再后续遍历_递归思想_分两端

       总结:    重建二叉树:其实就是根据前序和中序重建得到二叉树,得到后续,只要输出那边设置输出顺序即可 [编程题]重建二叉树 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的 ...

  6. 剑指offer_数组中的逆序对

    题目描述 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数P. 并将P对1000000007取模的结果输出. 即输出P%100 ...

  7. 剑指Offer_编程题之二维数组中的查找

    题目描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数.

  8. 剑指Offer_编程题之重建二叉树

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

  9. 剑指Offer_编程题_25

    题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用,否 ...

随机推荐

  1. validform表单验证插件最终版

    做个笔记,以后直接用吧. 报名界面: <%@ page language="java" pageEncoding="UTF-8" contentType= ...

  2. C#版--简单工厂模式

    为什么要用设计模式? 1.设计模式是前人根据经验总结出来的,使用设计模式,就相当于是站在了前人的肩膀上. 2.设计模式使程序易读.熟悉设计模式的人应该能够很容易读懂运用设计模式编写的程序. 3.设计模 ...

  3. 基于UDP协议的socket通信

    服务器端: 1.创建DatagramSocket,指定端口号 2.创建DatagramPacket 3.接收客户端发送的数据信息 4.读取数据 客户端: 1.定义发送信息 2.创建DatagramPa ...

  4. 面试之Java知识整理

    1.面向对象都有哪些特性 继承.封装.多态性.抽象 2.Java中实现多态的机制是什么? 继承与接口 3.Java中异常分为哪些种类 3.1按照异常需要处理的时机分为编译时异常(CheckedExce ...

  5. runtime ---- iOS

    1.runtime是什么?runtime是一套底层的C语言的API(包括C语言数据类型,C语言函数) 实际上平时我们写的OC代码底层都是基于runtime,实际上也就是最后都转成了runtime代码 ...

  6. PLSQL触发器

    触发器权限 数据库创建用户时想要在本用户下使用触发器,需要给用户触发器的权限 使用DBA用户执行  GRANT CREATE TRIGGER TO user_name; 如果想在当前用户下创建其他用户 ...

  7. https post

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

  8. 理解 ES6 语法中 yield 关键字的返回值

    在 ES6 中新增了生成器函数的语法,本文解释了生成器函数内 yield 关键字的返回值. 描述 根据语法规范,yield 关键字用来暂停和继续执行一个生成器函数.当外部调用生成器的 next() 方 ...

  9. BZOJ 3299: [USACO2011 Open]Corn Maze玉米迷宫(BFS)

    水题一道却交了4次QAQ,真是蒟蒻QAQ CODE: #include<cstdio>#include<iostream>#include<cstring>#inc ...

  10. Android 退出多Activity的application的方式

    在开发过程中,我们常常需要一个退出功能,来退出该应用的所有Activity.下面,我们列举一些退出应用的几种方式.以下用的源码点击查看源码地址 欢迎star,欢迎fork 利用ActivityCont ...