题目描述
我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:
所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。
输入格式
输A数据共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。
输出格式
输出可能的中序遍历序列的总数,结果不超过长整型数。
样例输入
abc
cba
样例输出
4
算法思想
对于一棵只有两个结点的二叉树来说,即根结点有一个子结点,给定其前序遍历[12][12][12]和后序遍历[21][21][21],其二叉树的形态可以有两种(如下图所示),中序遍历结果结果也有两种[21][21][21]、[12][12][12] 。
对于一棵三个结点的二叉树来说,即根结点有两个子结点,其二叉树的形态只有一种(如下图所示)。其前序遍历为[123][123][123],后序遍历为[231][231][231],中序遍历也只有一种情况[213][213][213]。
通过上面的分析可以发现,当父结点只有一个子结点时,给定前序和后序遍历序列,可以得到两种不同的中序遍历结果。
那么二叉树遍历问题就可以转化为求每个父结点只有一个子结点的情况数,然后利用乘法原理,每出现一次乘2,来计算中序遍历序列的总数。
那么如何判断某个结点是否只有一个子结点呢?其实只要出现前序[12][12][12]后序[21][21][21],这样就可以判断出111号结点只有一个儿子,也就是222号结点。
代码实现
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
string s1, s2;
cin >> s1 >> s2;
long long ans = 1;
for(int i = 0; i < s1.size() - 1; i ++)
for (int j = 1; j < s2.size(); j ++ )
if(s1[i] == s2[j] && s1[i + 1] == s2[j - 1]) ans = ans * 2;
cout << ans << endl;
return 0;
}