一、题目
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
(类似于LeetCode105)
二、分析及代码
1. 递归
(1)思路
前序遍历首先访问的是根节点,而中序遍历中根节点左、右的数字分别对应左、右子树的节点。
结合上述特征,可先找到根节点,再将问题分解为左、右子树的构造,递归求解。
(2)代码
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if (pre == null || pre.length != in.length)
return null;
return constructTree(pre, in, 0, pre.length - 1, 0, in.length - 1);
}
TreeNode constructTree(int [] pre, int [] in, int pbegin, int pend, int ibegin, int iend) {
int mid = 0;
while (pre[pbegin] != in[ibegin + mid]) {
mid++;
}
TreeNode root = new TreeNode(pre[pbegin]);
if (mid > 0)
root.left = constructTree(pre, in, pbegin + 1, pbegin + mid, ibegin, ibegin + mid - 1);
if (pend - pbegin - mid > 0)
root.right = constructTree(pre, in, pbegin + mid + 1, pend, ibegin + mid + 1, iend);
return root;
}
}
(3)结果
运行时间 259ms,占用内存 22216k。
三、其他
本题也可先依次添加左节点,并用栈记录添加的节点,到达当前最大深度后(栈顶 == 中序遍历当前值),回退并添加右子树。