详解重构二叉树

重建二叉树

http://www.nowcoder.com/questionTerminal/8a19cbe657394eeaac2f6ea9b0f6fcf6

本质上就是前序遍历的框架。
前序数组的第一个是根节点,找到中序数组它的索引 (可用map降低时间复杂度),中序数组以它为中心,左边是左子树,右边是右子树。
将大问题化成小问题,利用递归。 而指针可以在每轮递归中作为通信的工具。
上一层递归告诉下一层“你该缩小范围找了”。
left每一层递归返回给上一层的是刚刚遍历完的根节点的下一个,而right返回的是刚刚遍历完的(根节点当前位置 + 左子树的节点个数)的下一个。这跟前序数组的前序遍历性质有关,而我们又是基于前序数组来重构二叉树的。

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        //用map来缓存值和对应的索引,方便在递归方法中查找,降低时间复杂度
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i] , i);
        }
        return builTree(preorder, 0, preorder.length, inorder, 0, inorder.length, map);

    }
    private TreeNode builTree(int[] preorder, int p_start, int p_end, int[] inorder, int i_start, int i_end, HashMap<Integer, Integer> map){
        //递归出口 当指针相等时,左右子树已经找完了
        if(p_start == p_end)
            return null;

        int root_val = preorder[p_start];
        //构建节点
        TreeNode root = new TreeNode(root_val);
        //找到索引,利用这个位置将数组分成2部分, 前序数组的左部分就是左子树 
        int i_root_index = map.get(root_val);
        int leftNum = i_root_index - i_start;

        //前序遍历 注意左右子树的索引 start和end区间就是一个子树
        root.left = builTree(preorder, p_start + 1, p_start + leftNum + 1, inorder, i_start, i_root_index, map);
        root.right = builTree(preorder, p_start + leftNum + 1, p_end, inorder, i_root_index + 1, i_end, map);
        return root;
    }
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
06-05 15:27
点赞 评论 收藏
分享
完美的潜伏者许愿简历通过:我上表jd,请求封我做后端大将军的事,北京有消息了:竟然不许!!! 他们一定是看我没有实习,这才故意驳回我的请求!
点赞 评论 收藏
分享
牛客773130651号:巨佬,简历模板换成上下的,左右的很烦,hr看着不爽。。。科大随便乱杀,建议能保研就保研,不行也得考一下 ,985硕去干算法,比开发强多了。开发许多双非都能搞,学历优势用不上,算法有门槛
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务