栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/692768.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号