题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。树节点的定义如下:
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
思路:
前序遍历结果的第一个数字是二叉树根节点的值,在中序遍历结果中找到该值,其左边的数字为根节点左子树中节点的值,右边的数字为根节点右子树中节点的值。因此可以在前序遍历结果中确定左子树和右子树的节点对应的遍历结果的子序列。再对前序遍历结果和中序遍历结果中的子序列递归采用同样的算法,便可以重建二叉树。
代码(已在牛客网AC):
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
//保证代码健壮性
if(pre == null || in == null || pre.length != in.length)
return null;
return reConstructBinaryTree(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
private TreeNode reConstructBinaryTree(int[] pre, int preBegin, int preEnd, int[] in, int inBegin, int inEnd){
TreeNode root = new TreeNode(pre[preBegin]);
// 递归的结束情况
if(preBegin == preEnd){
if(inBegin == inEnd && pre[preBegin] == in[inBegin])
return root;
else
return null;
}
// 查找根节点值在中序遍历结果中的位置
int rootPos = inBegin;
for(int i = inBegin; i <= inEnd; i++){
if(in[i] == pre[preBegin])
{
rootPos = i;
break;
}
}
// 输入的中序遍历结果非法
if(rootPos == inEnd && in[rootPos] != pre[preBegin])
return null;
if(rootPos > inBegin){
root.left = reConstructBinaryTree(pre, preBegin + 1, preBegin + rootPos - inBegin, in, inBegin, rootPos - 1);
}
if(rootPos < inEnd){
root.right = reConstructBinaryTree(pre, preBegin + rootPos - inBegin + 1, preEnd, in, rootPos + 1, inEnd);
}
return root;
}
}