预购+后购到有序


11

任务

给定完整二叉树的前遍历和后遍历,返回其有序遍历。

遍历将表示为两个列表,两个列表均包含n个不同的正整数,每个列表唯一地标识一个节点。您的程序可能会采用这些列表,并使用任何合理的I / O格式输出结果顺序遍历。

您可以假设输入是有效的(也就是说,列表实际上表示对某些树的遍历)。

这是,因此以字节为单位的最短代码获胜。

定义

一个满二叉树是有限的结构节点,这里由唯一的正整数表示。

完整的二叉树是由单个节点组成的叶子

                                      1

或一个分支,由一个带有两个子树的节点组成(称为子树右子树),每个子树又是一个完整的二叉树:

                                      1
                                    /   \
                                  …       …

这是完整的二叉树的完整示例:

                                        6
                                      /   \
                                    3       4
                                   / \     / \
                                  1   8   5   7
                                     / \
                                    2   9

前序遍历的满二叉树的递归定义如下:

  • 包含节点n叶子的预遍历是列表[ n ]。
  • 包含节点n和子树(L,R)分支的预排序遍历是列表[ n ] +  排序(L)+  排序(R),其中+是列表串联运算符。

对于上面的树,就是[6,3,1,8,2,9,9,4,5,7]


完整二叉树的后遍历定义如下:

  • 包含节点n叶子的后序遍历是列表[ n ]。
  • 包含节点n和子树(L,R)分支的后序遍历是列表后序L)+  后序R)+ [ n ]。

对于上面的树,这是[1、2、9、8、3、5、7、4、6]


中序遍历满二叉树的递归定义如下:

  • 包含节点n叶子的有序遍历是列表[ n ]。
  • 包含节点n和子树(L,R)分支的有序遍历是列表有序L)+ [ n ] +  有序R)。

对于上面的树,这是[1、3、2、8、9、6、5、4、7]


结论:给定一对列表[6、3、1、8、2、9、4、5、7](前置)和[1、2、9、8、3、5、7、4、6](post)作为输入,您的程序应输出[1、3、2、8、9、6、5、4、7]

测试用例

每个测试用例均采用格式preorder, postorder → expected output

[8], [8] → [8]
[3,4,5], [4,5,3] → [4,3,5]
[1,2,9,8,3], [9,8,2,3,1] → [9,2,8,1,3]
[7,8,10,11,12,2,3,4,5], [11,12,10,2,8,4,5,3,7] → [11,10,12,8,2,7,4,3,5]
[1,2,3,4,5,6,7,8,9], [5,6,4,7,3,8,2,9,1] → [5,4,6,3,7,2,8,1,9]

由于保证输入具有特定的形状(完整的二叉树),因此您实际上并不需要两个输入,是吗?
feersum

二叉树是full,但不是complete,因此n元素树可以具有许多形状,通常,您确实需要两者。
林恩

我可以将节点表示为单个字母,为订单提供字符串。如第二个例子将成为:"CDE" and "DEC" give "DCE"?(如果我需要很多节点,甚至可以使用unicode字母)
Ton Hospel

@TonHospel我对此表示满意–可以说,您所做的只是稍微扩展了整数列表的定义,因为"CDE"[67, 68, 69]:: 并没有很大不同:)
Lynn

Answers:


2

Perl,69 66 62 56 53字节

包括+1的 -p

在STDIN上将后置顺序和后置顺序视为由空格分隔的一行(请注意前排和后置的顺序)。节点以唯一字母表示(任何非空格或换行符都可以)。

inpost.pl <<< "98231 12983"

inpost.pl

#!/usr/bin/perl -p
s%(.)(.)+\K(.)(.+)\3(\1.*)\2%$4$5$3$2%&&redo;s;.+ ;;

使用原始的纯数字格式需要格外小心,以准确识别单个数字并以73个字节为单位

#!/usr/bin/perl -p
s%\b(\d+)(,\d+)+\K,(\d+\b)(.+)\b\3,(\1\b.*)\2\b%$4$5,$3$2%&&redo;s;.+ ;;

用于

inpostnum.pl <<< "11,12,10,2,8,4,5,3,7 7,8,10,11,12,2,3,4,5"

-p;在末尾添加a ,因此您不需要last ;s;.* ;;->s;.* ;
Riley

@Riley我知道。这就是为什么我要;结尾的原因。但是-p实际上会增加程序\n;的末尾-e。在文件中,仅;当且仅当文件不以结尾时才添加\n。由于我想声明-p为+1而不是+3,因此该程序需要从命令行运行,因此请使用-e。我不想在输出中的寄生换行符然后我会得到
吨Hospel

如果您在命令行上运行它,是否不需要'它?如果您以自己的方式运行它(使用调用文件<<<),则可以;关闭最后一个。
莱利

@Riley这取决于对perl评分方法的解释。我通常将代码作为文件提交,因为我认为这不太短暂。但是,如果您查看我提交的内容,您会发现代码是否必须位于文件中(因为它具有'或使用do$0等),我总得分为-p+3(空格,负号,p),但是如果代码也可以工作你在哪里得到的命令行-e'自由我得分它+1,因为它可以与捆绑e
吨Hospel

好的,我只是不清楚命令行提交的得分如何。我没意识到你'是免费的。感谢您清理。
莱利2013年

3

Haskell,84 83字节

(a:b:c)#z|i<-1+length(fst$span(/=b)z),h<- \f->f i(b:c)#f i z=h take++a:h drop
a#_=a

2

JavaScript(ES6),100字节

f=(s,t,l=t.search(s[1]))=>s[1]?f(s.slice(1,++l+1),t.slice(0,l))+s[0]+f(s.slice(l+1),t.slice(l)):s[0]

I / O包含“安全”字符(例如字母或数字)的字符串。另一种方法,也是100个字节:

f=(s,t,a=0,b=0,c=s.length-1,l=t.search(s[a+1])-b)=>c?f(s,t,a+1,b,l)+s[a]+f(s,t,l+2+a,l+1,c-l-2):s[a]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.