题目来源:牛客网-剑指Offer专题
题目地址:重建二叉树
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题目解析
第 n + 1 n+1 n+1 次遇到这种题目了,简单写一下思路吧。
- 根据前序遍历的性质确定根节点,然后在中序遍历中查询根节点的位置。
- 这样就得到了中序遍历左右子树的范围了,接下来就是要求左子树的节点的个数。
- 求得左子树节点个数之后,我们就知道了前序遍历中左右子树的范围了。
- 建树的过程是递归的,我们要做的就是对左右子树重复上述过程。
(上图为一次求解过程的图示)
想看更详细解析的可以看这篇:L2-006 树的遍历-团体程序设计天梯赛GPLT
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
int r = pre.length - 1;
TreeNode root = buildTree(pre, in, 0, r, 0, r);
return root;
}
//[la,ra]为前序遍历序列范围,[lb,rb]为中序遍历序列的范围
public TreeNode buildTree(int [] pre,int [] in,
int la, int ra, int lb, int rb) {
if (la > ra || lb > rb) {
return null;
}
//num表示根节点的权值
int num = pre[la];
TreeNode rt = new TreeNode(num);
//p表示根节点在中序遍历序列中的位置
int p = lb;
while (p <= rb && in[p] != num) p++;
//cnt表示左子树节点的个数
int cnt = p - lb;
//递归建树
rt.left = buildTree(pre, in, la + 1, la + cnt, lb, p - 1);
rt.right = buildTree(pre, in, la+ cnt + 1, ra, p + 1, rb);
return rt;
}
}
如果本文对你有所帮助,要记得点赞哦~