Java描述 LeetCode,106. Construct Binary Tree from Inorder and Postorder Traversal 中序+后序 构建二叉树

大家好,我是河海哥,专注于后端,如果可以的话,想做一名code designer而不是普通的coder,一起见证河海哥的成长,您的评论与赞是我的最大动力,如有错误还请不吝赐教,万分感谢。一起支持原创吧!纯手打有笔误还望谅解。

1-1: description

☘️如题所示,就是已知中序数组和后序数组,构建出一棵二叉树出来。

1-2: recursion

☘️先手动模拟一下,中序和后续序列中如何构建一棵二叉树,这个老师应该都讲过,大家应该都会带,那么现在的主要问题就是,难在对数组切割上,递归上没有什么太多的东西,流程就是先从后序遍历中找到根,再利用值去中序中找到根节点,找到中序的根节点之后对数组进行分割,分割成左子树和右子树,并且根据长度 对后序遍历也进行分割,分割之后,就用递归,利用自述的先序和后续数组 调用递归函数就行了。于是我写出了这样的代码:

public TreeNode buildTree(int[] inorder, int[] postorder) {
//        if (inorder.length == 0 && postorder.length == 0)
    int postLength = postorder.length;
    int inorderLength = inorder.length;

    if (postLength == 0 && inorderLength == 0) {
        return null;
    }

    int rootValue = postorder[postLength - 1];
    TreeNode root = new TreeNode(rootValue);

    int inorderIndex;
    for (int i = 0; i < inorderLength; i++) {
        if (inorder[i] == rootValue) {
            inorderIndex = i;
            int[] leftInorder = Arrays.copyOfRange(inorder, 0, inorderIndex);
            int[] rightInorder = Arrays.copyOfRange(inorder, inorderIndex + 1, inorderLength);
            int[] leftPostOrder = Arrays.copyOfRange(postorder, 0, leftInorder.length);
            int[] rightPostOrder = Arrays.copyOfRange(postorder, leftInorder.length, leftInorder.length + rightInorder.length);
            TreeNode leftRoot = buildTree(leftInorder, leftPostOrder);
            TreeNode rightRoot = buildTree(rightInorder, rightPostOrder);
            root.left = leftRoot;
            root.right = rightRoot;
            break;
        }
    }
    return root;
}

☘️代码看上去还是比较清晰易懂的,但是复杂度很差,递归本身的复杂度+中序寻找根的复杂度+数组copy的复杂度,但是思路是对的。于是乎,看了下答案,答案也是利用下标,但是从头到位都是用的原来的数组,并且在中序序列中找根节点用map进行了优化。代码如下:

public TreeNode buildTree2(int[] inorder, int[] postorder) {
    for (int i = 0; i < inorder.length; i++) {
        inorderMap.put(inorder[i], i);
    }
    return traverse(inorder, postorder, 0, inorder.length - 1, 0, postorder.length - 1);
}

public TreeNode traverse(int[] inorder, int[] postorder, int inorderLeft, int inorderRight, int postOrderLeft, int postOrderRight) {
    if (inorderLeft > inorderRight) {
        return null;
    }
    int rootValue = postorder[postOrderRight];
    int inorderRootIndex = inorderMap.get(rootValue);
    int leftSubTreeLength = inorderRootIndex - inorderLeft;
    TreeNode root = new TreeNode(rootValue);
    root.left = traverse(inorder, postorder, inorderLeft, inorderRootIndex - 1, postOrderLeft, postOrderLeft + leftSubTreeLength - 1);
    root.right = traverse(inorder, postorder, inorderRootIndex + 1, inorderRight, postOrderLeft + leftSubTreeLength, postOrderRight - 1);
    return root;
}

☘️整个的难点就在切分上面,可以用一个例子,然后通过代码调试调试就能准确找到切分的位置啦。

1-3: iteration

☘️迭代好像略显复杂?我就没写了,感觉递归比较清晰易懂。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

河海哥yyds

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值