当前位置:网站首页>剑指Offer刷题记录——Offer 07.重建二叉树
剑指Offer刷题记录——Offer 07.重建二叉树
2022-07-17 05:22:00 【什么时候点菜】
输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。
假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

二叉树前序遍历的顺序为:
先遍历根节点;
随后递归地遍历左子树;
最后递归地遍历右子树。
二叉树中序遍历的顺序为:
先递归地遍历左子树;
随后遍历根节点;
最后递归地遍历右子树。
在「递归」地遍历某个子树的过程中,我们也是将这颗子树看成一颗全新的树,按照上述的顺序进行遍历。挖掘「前序遍历」和「中序遍历」的性质,我们就可以得出本题的做法。
思路
对于任意一颗树而言,前序遍历的形式总是
[ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]
即根节点总是前序遍历中的第一个节点。而中序遍历的形式总是
[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]
只要我们在中序遍历中定位到根节点,那么我们就可以分别知道左子树和右子树中的节点数目。由于同一颗子树的前序遍历和中序遍历的长度显然是相同的,因此我们就可以对应到前序遍历的结果中,对上述形式中的所有左右括号进行定位。
这样以来,我们就知道了左子树的前序遍历和中序遍历结果,以及右子树的前序遍历和中序遍历结果,我们就可以递归地对构造出左子树和右子树,再将这两颗子树接到根节点的左右位置。
细节
在中序遍历中对根节点进行定位时,一种简单的方法是直接扫描整个中序遍历的结果并找出根节点,但这样做的时间复杂度较高。我们可以考虑使用哈希表来帮助我们快速地定位根节点。对于哈希映射中的每个键值对,键表示一个元素(节点的值),值表示其在中序遍历中的出现位置。在构造二叉树的过程之前,我们可以对中序遍历的列表进行一遍扫描,就可以构造出这个哈希映射。在此后构造二叉树的过程中,我们就只需要 O(1)O(1) 的时间对根节点进行定位了。
下面的代码给出了详细的注释。
class Solution {
private Map<Integer, Integer> indexMap;
public TreeNode myBuildTree(int[] preorder, int[] inorder, int preorder_left, int preorder_right, int inorder_left, int inorder_right) {
if (preorder_left > preorder_right) {
return null;
}
// 前序遍历中的第一个节点就是根节点
int preorder_root = preorder_left;
// 在中序遍历中定位根节点
int inorder_root = indexMap.get(preorder[preorder_root]);
// 先把根节点建立出来
TreeNode root = new TreeNode(preorder[preorder_root]);
// 得到左子树中的节点数目
int size_left_subtree = inorder_root - inorder_left;
// 递归地构造左子树,并连接到根节点
// 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
root.left = myBuildTree(preorder, inorder, preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1);
// 递归地构造右子树,并连接到根节点
// 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
root.right = myBuildTree(preorder, inorder, preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
// 构造哈希映射,帮助我们快速定位根节点
indexMap = new HashMap<Integer, Integer>();
for (int i = 0; i < n; i++) {
indexMap.put(inorder[i], i);
}
return myBuildTree(preorder, inorder, 0, n - 1, 0, n - 1);
}
}
边栏推荐
猜你喜欢

SSH remote login service
高防服务器是如何确认哪些是恶意IP/流量?ip:103.88.32.XXX

Commande awk du troisième épéiste - - interception
![[ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :](/img/dd/054af819c8bdca31bd135495386fb4.png)
[ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :

Intranet penetration server building tutorial, NPs use tutorial

UCloud(优刻得) 上海 ARM 云服务器评测

关于文件上传下载问题

Steam游戏服务器配置选择 IP

How to set primary key self growth in PostgreSQL database
Xiaodi network security notes - Information Collection - architecture, construction, WAF (8)
随机推荐
Commande awk du troisième épéiste - - interception
小迪网络安全笔记-信息收集-架构、搭建、waf(8)
What happened to redraiment
[ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
X11 forwarding
Tianyi cloud Hangzhou virtual machine (VPS) performance evaluation
1.服务器是什么?
类与super、继承
Performance evaluation and comparison of lightweight application servers of major cloud service manufacturers, Alibaba cloud, Tencent cloud, Huawei cloud, and ucloud
IP fragment是什么意思?如何防御IP fragment攻击?
Total price contract, cost compensation contract, labor contract
Tcp/ip four layer model and related configurations of F5
递归访问目录,打印斐波那契数列,高阶函数
Intranet penetration server building tutorial, NPs use tutorial
Manual string comparison (pointer question)
关于文件上传下载问题
Technical specification for secure electronic signature and password gm/t 0031 | GB / T 38540 format OpenSSL package analysis
University
telnet安装
University