剑指 Offer 07. 重建二叉树(Java实现 超详细注释!)

本文介绍了一种使用列表和递归实现的二叉树重建算法。通过前序和中序遍历序列构建二叉树,详细解释了递归过程及关键步骤。适合初学者理解和实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

剑指 Offer 07. 重建二叉树

使用列表+递归实现,虽然时间复杂度比较高,因为列表通过值查索引的效率不高,但是胜在好理解!加了详细的注释,方便自己日后复习,同时也希望可以帮助其他人,如有错误,欢迎指正

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        // 用两个ArrayList分别存储前序和中序遍历的数组
        // 前序的列表是为了更方便地得到根节点
        // 中序的列表是为了更方便地切割左右子树
        List<Integer> preorder_list = new ArrayList<Integer>();
        List<Integer> inorder_list = new ArrayList<Integer>();
        for (int i = 0; i < preorder.length; i++){
            preorder_list.add(preorder[i]);
            inorder_list.add(inorder[i]);
        }
        // 递归,不断通过递归的方法去生成左右子树,并连接到根节点上
        return recursion(preorder_list,inorder_list);

    }

    private TreeNode recursion(List<Integer> preorder_list,List<Integer> inorder_list){
        // 递归的结束条件:当中序遍历的列表空了说明该根节点已经没有该递归方向的子树了,那么该节点在该方向的子树就是null,直接返回null即可
        if (inorder_list.isEmpty()){
            return null;
        }
        /**当前树的根节点其实就是前序遍历列表的第一个节点,我们直接先构建一下根节点;
        这里要注意的是我们为了每次递归传入的都是preorder_list,再构建完该树的根节点后,需要remove列表中的这个值
        注意我们能不停地使用preorder_list的第一个元素作为根节点,是因为我们前序遍历的顺序与构建整棵树的顺序是一致的(哈哈哈,我个人的理解,如果有错误请指正,感谢!)*/
        TreeNode node = new TreeNode(preorder_list.remove(0)); 
        /**有了根节点后,我们需要继续构建它的左右子树,而左右子树需要通过切割中序遍历的列表得到,中序遍历列表的根节点左边是左子树,右边是右子树;            所以我们找到根节点在中序遍历的索引,利用这个索引来切割*/
        int node_index = inorder_list.indexOf(node.val);
        // 把切割后的左子树和右子树分别再进行递归,知道达到递归退出的条件即可;
        // 此外preorder_list这个参数我们前面说过了,每次都拿出第一个元素做根节点即可
        node.left = recursion(preorder_list,inorder_list.subList(0,node_index));
        // 注意subList()这个方法的右边界是不包括的,所以右边界我们这里用inorder_list.size(),而不是inorder_list.size() - 1
        node.right = recursion(preorder_list,inorder_list.subList(node_index + 1,inorder_list.size()));
        // 每次递归都需要返回一个根节点,给上一层的根节点作为一棵子树
        return node;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值