《剑指offer》第六天:重建二叉树
时间:2022-07-23
本文章向大家介绍《剑指offer》第六天:重建二叉树,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
❝恶魔:说出你的三个愿望! 男:请你实现我的第二个愿望。 恶魔:然后呢? 男:请你实现我的第一个愿望。 恶魔:Exception in thread "main" java.lang.StackOverflowError —— 小浩 ❞
重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列 {1,2,4,7,3,5,6,8}
和中序遍历序列 {4,7,2,1,5,3,8,6}
,则重建二叉树并返回。
原题题目
思路分析
动图展示
原文参考
解法
在二叉树的前序遍历序列中,第一个数字总是根结点的值。在中序遍历序列中,根结点的值在序列的中间,左子树的结点位于根结点左侧,而右子树的结点位于根结点值的右侧。
遍历中序序列,找到根结点,递归构建左子树与右子树。
注意添加特殊情况的 if
判断。
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
/**
* 重建二叉树
*
* @param pre 先序序列
* @param in 中序序列
* @return 二叉树根结点
*/
public TreeNode reConstructBinaryTree(int[] pre, int[] in) {
if (pre == null || in == null || pre.length != in.length) {
return null;
}
int n = pre.length;
return constructBinaryTree(pre, 0, n - 1, in, 0, n - 1);
}
private TreeNode constructBinaryTree(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
TreeNode node = new TreeNode(pre[startPre]);
if (startPre == endPre) {
if (startIn == endIn) {
return node;
}
throw new IllegalArgumentException("Invalid input!");
}
int inOrder = startIn;
while (in[inOrder] != pre[startPre]) {
++inOrder;
if (inOrder > endIn) {
new IllegalArgumentException("Invalid input!");
}
}
int len = inOrder - startIn;
if (len > 0) {
// 递归构建左子树
node.left = constructBinaryTree(pre, startPre + 1, startPre + len, in, startIn, inOrder - 1);
}
if (inOrder < endIn) {
// 递归构建右子树
node.right = constructBinaryTree(pre, startPre + len + 1, endPre, in, inOrder + 1, endIn);
}
return node;
}
}
测试用例
- 普通二叉树(完全二叉树;不完全二叉树);
- 特殊二叉树(所有结点都没有左/右子结点;只有一个结点的二叉树);
- 特殊输入测试(二叉树根结点为空;输入的前序序列和中序序列不匹配)。
我把我写的所有题解整理成了一本电子书放在了 github 上,三天内冲击到 github 排行榜榜首!近 5w 人下载阅读!要获取的话,直接进入下方链接就可以了(记得给我点个 star):
https://github.com/geekxh/hello-algorithm
- JavaScript设计模式与开发实践 - 策略模式
- 二叉树的深度
- [html5] (Notification) 桌面通知
- React第三方组件4(状态管理之Reflux的使用④TodoList下)
- Leetcode-Easy 155. Min Stack
- Leetcode-Easy 72. Edit Distance
- React第三方组件4(状态管理之Reflux的使用③TodoList中)
- Leetcode-Easy21. Merge Two Sorted ListsDefinition for singly-linked list.class ListNode:def init(sel
- Burp Suite详细使用教程-Intruder模块详解
- 逆元的三种解法(附详细证明)
- JavaScript设计模式与开发实践 - 单例模式
- Leetcode-Easy 141. Linked List Cycle
- 【DataMagic】如何在万亿级别规模的数据量上使用Spark
- 51nod1004 n^n的末位数字
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 用Python爬取淘宝4403条大裤衩数据进行分析,终于找到可以入手的那一条
- Python 微信机器人:属于自己的微信机器人制作,简单易懂。图灵机器人接口api调用。
- 最全总结:把模块当做脚本来执行的 7 种案例及其原理
- 经典八种排序算法总结(带动画演示)
- bokeh作图过程报错解决方法兼Pycharm如何升级安装包的方法
- 一、html 基础
- 二、css3基础
- 三. CSS layout(布局)
- 四. css 布局之 float
- Python+selenium 自动化-读取excel记录的脚本执行登陆操作实战演示
- 详细讲解!从JVM直到类加载器
- PyQt5 图形界面-实现按钮监听事件
- Python 技术篇-文件操作:文件的读取和写入
- Salesforce Javascript(一) Promise 浅谈
- Python 技巧篇-英文单词首字母大小写转换功能实例演示,字符串切片实现