重建二叉树(前序中序、中序后序、前序后序)

本文探讨了如何利用前序、中序、后序遍历序列来重建二叉树,包括LeetCode的654题(最大二叉树)以及105题和106题的解法,分别涉及前序中序、中序后序的构建策略。此外,还提及了889题,即根据前序和后序遍历构造二叉树的方法。
摘要由CSDN通过智能技术生成

654. 最大二叉树

class Solution {
    public TreeNode constructMaximumBinaryTree(int[] nums) {
        return construct(nums, 0, nums.length -1);
    }

    public TreeNode construct(int[] nums, int left, int right) {
        if (left > right) {
            return null;
        }

        int index = left;
        int max = nums[index];
        for(int i = left; i<=right; i++){
            if (max < nums[i]) {
                index = i;
                max = nums[i];
            }
        }
        TreeNode root = new TreeNode(nums[index]);
        root.left = construct(nums, left, index -1);
        root.right = construct(nums, index + 1, right);

        return root;
    }
}

前序中序:105. 从前序与中序遍历序列构造二叉树

class Solution {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return CreateByPreMid(preorder, inorder, 0, 0, preorder.length);
    }

    public TreeNode CreateByPreMid(int[] preorder, int[] inorder, int index_pre, int index_in, int n) {
        if (n == 0) {
            return null;
        }
        TreeNode p = new TreeNode(preorder[index_pre]);
        int i;                          //这里的i相当于左子树的个数
        for (i = 0; i < n; i++) {
            if (preorder[index_pre] == inorder[index_in + i])
                break;
        }
        p.left = CreateByPreMid(preorder, inorder, index_pre + 1, index_in, i);
        p.right = CreateByPreMid(preorder, inorder, index_pre + i + 1, index_in + i + 1, n - i - 1);
        return p;
    }
}

中序后序:106. 从中序与后序遍历序列构造二叉树

class Solution {
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        int n = postorder.length;
        return CreateByMidPost(inorder, postorder, 0, n-1, n);
    }

    /** index_in是inorder数组的开始下标 index_post是postorder数组的结束下标
     *   n是二叉树的大小
     *   后序遍历的尾节点就是根节点 所以postorder[index_post]就是树根节点的值、
     *   再找到中序遍历中对应的值 该值左边的值就是左子树对应的 右边的值就是右子树对应的
     *   左子树 右子树的情况同样如此
     */
    public TreeNode CreateByMidPost(int[] inorder, int[] postorder, int index_in, int index_post, int n) {
        if (n == 0)
            return null;
        //后序遍历的最后就是根节点
        TreeNode p = new TreeNode(postorder[index_post]);
        //中序遍历根节点的位置在中间,找到下标i,这里的i也相当于左子树的个数
        int i;                          
        for (i = 0; i < n; i++) {
            if (inorder[index_in + i] == postorder[index_post])
                break;
        }
        //左子树大小是n - i - 1,前序遍历数组的开始下标就是index,后序遍历数组的结束下标就是	index_post -(n-i) ,n-1表示的是左子树右边大小(包含右子树和当前结点自身) 
        p.left = CreateByMidPost(inorder, postorder, index_in, index_post - n + i, i);
        //右子树大小是n - i - 1,前序遍历数组的开始下标就是index+i+1,后序遍历数组的结束下标就是	index_post-1 
        p.right = CreateByMidPost(inorder, postorder, index_in + i + 1, index_post - 1, n - i - 1);
        return p;
    }
}

前序后序:889. 根据前序和后序遍历构造二叉树

class Solution {
    public TreeNode constructFromPrePost(int[] pre, int[] post) {
        return CreateByPrePost(pre, post, 0, 0, pre.length);
    }

    public TreeNode CreateByPrePost(int[] pre, int[] post, int index_pre, int index_post, int n) {

        if (n == 0) {
            return null;
        }
        TreeNode p = new TreeNode(pre[index_pre]);
        if (n == 1) {
            return p;
        }
        int i;                          //这里的i相当于左子树的个数
        for (i = 0; i < n; i++) {
            if (pre[index_pre + 1] == post[index_post + i])
                break;
        }
        p.left = CreateByPrePost(pre, post, index_pre + 1, index_post, i + 1);
        p.right = CreateByPrePost(pre, post, index_pre + i + 2, index_post + i + 1, n - i - 2);
        return p;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值