您的位置:首页 > Web前端

剑指offer(四)重建二叉树

2017-08-27 20:22 579 查看
题目

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

案例

输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

分析

对于这道题,之前都是接触二叉树的遍历,对于逆向重建真的没有一点思路,然后想找规律做出来,最终想法受限,结果失败了。

然后看网上大神的做法和思路,终于对二叉树等又有了新的认识。

他们的思路就是把二叉树无限拆分
4000
,从根节点开始,每个节点都是一个新的二叉树,然后每次只取根节点。

这样,递归的中心只需要找到每次二叉树的范围就好。

解题代码:递归

/**
* 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) {

//第一步都需要判断输入合法性,两个数组都不能为空,并且都有数据,而且数据的数目相同
if( pre == null || in == null || pre.length != in.length || pre.length < 1 )
return null;
return construct(pre, 0, pre.length - 1, in, 0, in.length - 1);
}

/**
* 递归重建二叉树
* @param pre 前序遍历
* @param ps  前序遍历的开始位置
* @param pe  前序遍历的结束位置
* @param in  中序遍历
* @param is  中序遍历的开始位置
* @param ie  中序遍历的结束位置
* @return 树的根结点
*/
public static TreeNode construct(int[] pre, int ps, int pe, int[] in, int is, int ie) {

// 判断开始位置是否大于结束位置
if( ps > pe )
return null;

//前序遍历第一个位置,即为根节点
int value = pre[ps];
//创建当前的根节点,并且为节点赋值
TreeNode treeNode = new TreeNode(value);
if( ps == pe )
return treeNode;

int index = is;//中序遍历的开始位置

//寻找中序遍历的根节点
while( index <= ie && in[index] != value ) {
index++;
}

if( index > ie )
throw new RuntimeException("Invaild input");

// 递归构建当前根结点的左子树,左子树的元素个数:index-is+1个
// 左子树对应的前序遍历的位置在[ps + 1, ps + index - is]
// 左子树对应的中序遍历的位置在[is, index - 1]
treeNode.left = construct(pre, ps + 1, ps + index - is, in, is, index - 1);

// 递归构建当前根结点的右子树,右子树的元素个数:ie-index个
// 右子树对应的前序遍历的位置在[pe - ie + index + 1, pe]
// 右子树对应的中序遍历的位置在[index + 1, ie]
treeNode.right = construct(pre, pe - ie + index + 1, pe, in, index + 1, ie);

// 返回创建的根结点
return treeNode;
}
}


总结

对于寻找每次递归二叉树的范围,只需要每次找到固定的两个点,然后做加减乘除即可。

认识到了不一样的二叉树,自己还有待加强。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: