剑指offer(四)重建二叉树

来源:互联网 发布:php compact 编辑:程序博客网 时间:2024/05/23 12:36
  • 题目
    • 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
  • 案例
    • 输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
  • 分析
    • 对于这道题,之前都是接触二叉树的遍历,对于逆向重建真的没有一点思路,然后想找规律做出来,最终想法受限,结果失败了。
    • 然后看网上大神的做法和思路,终于对二叉树等又有了新的认识。
    • 他们的思路就是把二叉树无限拆分,从根节点开始,每个节点都是一个新的二叉树,然后每次只取根节点。
    • 这样,递归的中心只需要找到每次二叉树的范围就好。
  • 解题代码:递归
/** * 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;    }}
  • 总结
    • 对于寻找每次递归二叉树的范围,只需要每次找到固定的两个点,然后做加减乘除即可。
    • 认识到了不一样的二叉树,自己还有待加强。
原创粉丝点击