我在编码挑战中遇到一个问题。
完整的二叉树是一棵二叉树,其中除叶节点之外的每个节点都有两个子节点,并且边缘高度为h
的树的最后一级有2^h
个叶节点。 / p>
您的任务很简单,给定遍历post-order
遍历完整的二叉树,请打印其in-order
遍历。
二叉树中的元素属于字符类型,即每个节点存储一个字符值。
输入/输出格式
输入格式:
只有一个字符串输入表示后遍历。
约束:
1 <= input.length <= 1000
输出格式:
输出一个字符串,表示二叉树的有序遍历
样品
样本输入0:
BCA
样本输出0:
BAC
答案 0 :(得分:1)
您可以动态地进行递归操作。
left
,right
,root
。left
,root
,right
。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
是一棵完整的树,但不是完美的树。答案 1 :(得分:1)
我确实准备好了完整的答案,但是@EricWang击败了我以实现该目标。因此,这是一个补充性答案,详细描述了该过程。请接受他的回答。
我将使用后遍历DEBFGCA
,因为考虑更多的节点很有用。
因为树是完整的,所以对于任何给定的节点,我们知道左侧的子代数与右侧的子代数相同。因此,我们可以查看后遍历DEBFGCA
并知道它具有结构LLLRRRN
,其中L
是左子树R
的后遍历是右子树的后序遍历,N
是节点本身。
更一般地说,我们知道左子树的后序遍历是字符0
至(tree.length - 1)/2 - 1
,右子树的后序遍历是字符(tree.length -1)/2 - 1
至tree.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
。