遍历问题
Time Limit:1000MS Memory Limit:65536K
Total Submit: Accepted:
Description
我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:
A A A A
/ / / /
B B B B
/ / / /
C C C C
所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。
Input
共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。
Output
输出可能的中序遍历序列的总数,结果不超过长整型数。
Sample Input
abc
cba
Sample Output
4
Source
#include<iostream>
#include<string>
using namespace std;
string s1,s2;
bool check(string &a,string &b) //前序可能的左子树与后序可能的左子树是否相配
{
int i;
if( a.length()==0 )
{ return true; }
else
{
if (a[0]==b[b.length()-1])
{
for (i=1;i<=a.length()-1;i++)
{
if( b.find(a[i])>b.length() ) return false; //unfind
}
return true;
}
else
return false;
}
}
int f(string l1,string l2)
{
int n,m,i;
string l1l,l1r,l2l,l2r;//l1,l2的左右子树
m=0;
n=l1.length();
if ((n==0) || (n==1)) //递归结束条件
{ return 1; }
else
{
for (i= n-1; i>=0; i--)//左子树右子树的可能,i为中间位置
{
l1l.assign(l1,2-1,i);
l1r.assign(l1,i+2-1,n-i-1);
l2l.assign(l2,1-1,i);
l2r.assign(l2,i+1-1,n-i-1);
if( check(l1l,l2l)&& check(l1r,l2r) )
{ m=m+f(l1l,l2l)*f(l1r,l2r); }//分步相加,分类相乘
}
}
return m;
}
int main()
{
int x;
cin>>s1>>s2;
x=f(s1,s2);
cout<<x<<endl;
return 0;
}