【问题标题】:Binary tree Inorder traversal from only postorder traversal provided仅提供后序遍历的二叉树中序遍历
【发布时间】:2019-07-24 19:56:44
【问题描述】:

我在编码挑战中遇到了一个问题。

完全二叉树是一种二叉树,其中除叶节点外的每个节点都有两个子节点,并且边缘高度为h 的树的最后一层具有2^h 叶节点。

你的任务很简单,给定完整二叉树的post-order遍历,打印它的in-order遍历。

二叉树中的元素是字符类型,即每个节点存储一个字符值。


输入/输出格式

输入格式:

只有一个字符串输入表示后序遍历。

约束:

1

输出格式:

输出一个表示二叉树中序遍历的字符串


示例

示例输入 0:

BCA

样本输出 0:

BAC

【问题讨论】:

  • 先通过谷歌搜索。
  • 我做到了。我找不到解决方案。如果可以的话,请分享链接。

标签: algorithm binary-tree


【解决方案1】:

您可以通过递归来动态完成。


机制

  • 将树拆分为 3 部分:leftrightroot
  • 按顺序重新加入他们:leftrootright
  • 递归拆分,直到子树的长度为一。

代码 - 在Java

PostToInOrder.java

public class PostToInOrder {
    public static String convert(String post) {
        checkPerfect(post); // check whether tree is perfect,

        return convertInner(post);
    }

    private static String convertInner(String post) {
        int len = post.length();
        if (len == 1) return post; // base case,

        String left = post.substring(0, len >> 1); // left of post,
        String right = post.substring(len >> 1, len - 1); // right of post,
        char root = post.charAt(len - 1); // root of post,

        return convertInner(left) + root + convertInner(right);
    }

    private static void checkPerfect(String tree) {
        if (!isPerfect(tree)) throw new IllegalArgumentException("input is not perfect tree, size: " + tree.length());
    }

    private static boolean isPerfect(String tree) {
        int len = tree.length();
        if (len < 1) return false;

        while (len != 0) {
            if ((len & 1) == 0) return false;
            len >>= 1;
        }

        return true;
    }
}

PostToInOrderTest.java:
(单元测试,通过TestNG

import org.testng.Assert;
import org.testng.annotations.Test;

public class PostToInOrderTest {
    @Test
    public void test() {
        Assert.assertEquals(PostToInOrder.convert("BCA"), "BAC");
        Assert.assertEquals(PostToInOrder.convert("02146538A9CEDB7"), "0123456789ABCDE");

        Assert.assertEquals(PostToInOrder.convert("A"), "A"); // single element,
    }

    @Test(expectedExceptions = IllegalArgumentException.class)
    public void test_invalid_empty() {
        PostToInOrder.convert("");
    }

    @Test(expectedExceptions = IllegalArgumentException.class)
    public void test_invalid_notPerfect() {
        PostToInOrder.convert("AB");
    }
}

顺便说一句:

  • 所描述的树是perfect binary tree
    它是完全二叉树的子类型。
    一棵完整的树不一定是完美的,它的最后一层可能缺少一些叶子。
    例如 AB 是一棵完整的树,但不是完美的树。

【讨论】:

    【解决方案2】:

    我确实准备好了一个完整的答案,但@EricWang 在实施方面击败了我。因此,这是一个补充答案,更详细地描述了该过程。请接受他的答案。


    我将使用后序遍历DEBFGCA,因为考虑更多节点会很有用。

    因为树是完整的,对于任何给定的节点,我们知道左边的孩子的数量与右边的孩子的数量相同。因此我们可以看一下后序遍历DEBFGCA,知道它有LLLRRRN的结构,其中L是左子树的后序遍历,R是左子树的后序遍历右子树,N 是节点本身。

    更一般地,我们知道左子树的后序遍历是字符0(tree.length - 1)/2 - 1,右子树的后序遍历是字符(tree.length -1)/2 - 1tree.length - 2。该节点是最后一个字符,位于tree.length - 1

    显然,要将其更改为有序遍历,我们只需识别左右子树,将它们更改为有序遍历,然后返回LLLNRRR。我们可以使用递归将左右子树转换为有序的。

    例如,以DEBFGCA 开头。我们知道结构是LLLRRRN,所以左子树是DEB,右子树是FGC,节点是A。我们想把DEB 变成有序...

    处理DEB。我们知道左子树是D,右子树是E,节点是B。两个子树的长度都是 1,叶子也是。不需要进一步的递归。返回LNR,即DBE

    处理FGC。和以前一样,返回FCG

    现在我们知道有序的左边是DBE,右边是FCG。返回LLLNRRR,即DBEAFCG

    【讨论】:

    • 非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2021-03-08
    • 2020-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-09
    相关资源
    最近更新 更多