题目描述
我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:
所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。
输入格式
输A数据共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。
输出可能的中序遍历序列的总数,结果不超过长整型数。
输入输出样例
输入 #1
abc cba
输出 #1
4
要写出这一题我们需要知道一个知识点,那就是只拥有前序遍历和后序遍历为什么不能准确判断中序遍历。接下来可以告诉你答案,因为我们无法从前序遍历和后序遍历中判断左右子树。前序遍历就是根左右,后序遍历是左右根,问题就是前序的abc和后序的cba无论是只有左子树还是只有右子树都可以符合遍历顺序,所以,我们可以以此得到,那些只有一个子树的节点就是改变中序遍历的关键,然后又根据每出现一个这样的节点就分叉出2种不同的情况,那么就是总共就是2^n种中序遍历序列,n是子树中只有一个子树的节点的个数。
那么问题又来了,怎么从前序和后序遍历中判断只有一个子树的节点呢?你想想,以前序abc后序cba为例,如果bc是a的左右子树,那么后序遍历应该是bca对吧。例子给出的后序是cba,这,就表示着a只有一个子树。如果还不明白,可以再自己举几个例子。由此我们得出一个结论,如果前序遍历的fro[i]和fro[i+1]在后序遍历中倒过来排列,那么就代表fro[i]就是只有一个子树。
具体实现看代码:
#include <stdio.h>
#include <string.h>
#include <math.h>
long long int ans=0;
int main()
{
char a[10000],b[10000];
gets(a);
gets(b);
for(int i=0;i<strlen(a)-1;i++)
for(int j=0;j<strlen(b);j++)
if(b[j]==a[i])
{
if(a[i+1]==b[j-1])
ans++;
}
printf("%d",(long long int)pow(2,ans));
}
代码十分简短,理解了就很容易写出来了。