发布于 

剑指 Offer.07-重建二叉树

剑指 Offer.07-重建二叉树

题目链接

<剑指 Offer 07. 重建二叉树>

问题描述

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字

官方解法

利用先序遍历与中序遍历的性质,寻找当前树的根节点,再依次对左右子树进行调用即可

  • 前序遍历:[根节点,左子树,右子树]
  • 中序遍历:[左子树,根节点,右子树]

根据两种遍历的特性,可得以下推论

  1. 先序遍历的首元素为树的根节点
  2. 根据先序遍历的根节点,可简单将中序遍历划分为[左子树,根节点,右子树]
  3. 根据中序遍历左右节点的数量,可将前序遍历划分为[根节点,左子树,右子树]

具体方案

利用上述特性,确定当前树的根节点,左子树的根节点,右子树的根节点,并通过递归调用,最终复原完整的树

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
// 辅助递归操作执行
int[] preorder;
HashMap<Integer,Integer> dic = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
// 将整个中序遍历的数组存储为hash表
for(int i=0;i<inorder.length;i++){
dic.put(inorder[i],i);
}
return recur(0,0,inorder.length-1);
}

TreeNode recur(int root,int left,int right){
if(left > right) return null;
// 根据先序遍历 创建根节点
TreeNode node = new TreeNode(preorder[root]);
// 获取先序遍历节点在中序遍历数组中的位置
int i = dic.get(preorder[root]);
// 划分左右子树
node.left = recur(root+1,left,i-1);
//其中参数中的第一项是在先序遍历中根节点的位置,后面通过中序遍历控制范围
node.right = recur(root+i-left+1,i+1,right);
return node;
}
}

图解


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 @John Doe 创建,使用 Stellar 作为主题。