点击蓝色“五分钟学算法”关注我哟
加个“星标”,天天中午 12:15,一起学算法
作者 | 程序员小吴
来源 | 五分钟学算法
题目描述
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [28,16,13,22,30,29,43]
中序遍历 inorder = [13,16,22,28,29,30,43]
返回如下的二叉树:
28
题目解析
先来了解一下前序遍历、中序遍历、后序遍历是什么。
前序遍历:遍历顺序为 父(根)节点 -> 左子节点 -> 右子节点
中序遍历:遍历顺序为 左子节点 -> 父(根)节点 -> 右子节点
后序遍历:遍历顺序为 左子节点 -> 右子节点 -> 父(根)节点
再说明一个结论:前序/后序 + 中序遍历可以确定一棵唯一二叉树。
题目中给出的是 前序 + 中序 的组合,那么我们仔细观察对比一下 前序遍历 与 中序遍历。
前序中左起第一位
28
肯定是根结点,以此为根据找到中序中根结点的位置rootIdx
中序中根结点左边就是左子树结点,右边就是右子树结点,即
[左子树结点,根结点,右子树结点]
,我们就可以得出左子树结点个数为int leftLen = rootIdx - leftIdx
前序中结点分布应该是:
[根结点,左子树结点,右子树结点]
根据前一步确定的左子树个数,可以确定前序中左子树结点和右子树结点的范围
如果我们要递归生成二叉树的话,下一层递归应该是:
左子树:
root->left = buildTree(前序左子树范围,前序起始下标,前序结束下标,中序开始下标);
;右子树:
root->right = buildTree(前序左子树范围,前序起始下标,前序结束下标,中序开始下标);
。
两个注意点:
每一层递归都要返回当前根结点
root
;为了避免在递归过程中线性查找,可以借助 哈希表 来储存中序的元素与下标
动画描述
![ee92852e5a9d41fa34e70cbc5ce72e4c.gif](https://img-blog.csdnimg.cn/img_convert/ee92852e5a9d41fa34e70cbc5ce72e4c.gif)
图片描述
![3e9621772481050dd03f30eea0a9f12f.png](https://img-blog.csdnimg.cn/img_convert/3e9621772481050dd03f30eea0a9f12f.png)
![10ea94a5ba9b758080e70f24b684e126.png](https://img-blog.csdnimg.cn/img_convert/10ea94a5ba9b758080e70f24b684e126.png)
![d1353a0126efb65926ba966abcb9df96.png](https://img-blog.csdnimg.cn/img_convert/d1353a0126efb65926ba966abcb9df96.png)
![d1353a0126efb65926ba966abcb9df96.png](https://img-blog.csdnimg.cn/img_convert/d1353a0126efb65926ba966abcb9df96.png)
代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
复杂度分析
时间复杂度:O(n) 。
空间复杂度:O(n)。借助哈希表这种数据结构,需要额外的存储空间,因此空间复杂度为 O(n)。
知识点
二叉树、递归
热门推荐
1.【程序员】全球最厉害的 14 位程序员
2.【GitHub】我在 GitHub 上看到了一个丧心病狂的开源项目!
3.【算法】动画:七分钟理解什么是KMP算法
4.【数据结构】十大经典排序算法动画与解析,看我就够了!