我們都很熟悉二叉樹的前序、中序、後序遍歷,在數據結構中常提出這樣的問題:已知一棵二叉樹的前序和中序遍歷,求它的後序遍歷,相應的,已知一棵二叉樹的後序遍歷和中序遍歷序列你也能求出它的前序遍歷。然而給定一棵二叉樹的前序和後序,你卻不能確定其中序遍歷序列,考慮如下圖中的幾棵二叉樹:
所有這些二叉樹都有着相同的前序遍歷和後序遍歷,但中序遍歷卻不相同。
輸入文件共2行,第一行表示該樹的前序遍歷結果,第二行表示該樹的後序遍歷結果。輸入的字符集合爲{a-z},長度不超過26。
輸出文件只包含一個不超過長整型的整數,表示可能的中序遍歷序列的總數。
abc
cba
4
這道題是書上的原題,其中給了兩種方法:
法一——搜索:
法二——性質:
很明顯,已知一棵二叉樹的前序遍歷和後序遍歷,判斷中序遍歷時,其可能性只與沒有兄弟節點的葉節點的位置有關。
假設沒有兄弟節點的葉節點共有n個,則可能性邊有2^n個。(就不證明了)
那麼,如何計算n的值呢?
下面有一個性質:
- 一棵二叉樹的前序遍歷a1a2a3...ai和後序遍歷b1b2b3...bi有一種關係:
- 沒有兄弟節點的葉節點的根 在a序列下標爲i,
在b序列下標爲j
則有 a[i-1] == b[j+1]
這是因爲當根只有一棵子樹時,前序和後序遍歷都是先遍歷它的孩子,而且是唯一的一個孩子,所以相對位置是一樣的。
代碼如下:
#include <iostream>
#include <cstring>
using namespace std;
int ans;
string pre,back;
int main()
{
cin>>pre>>back;ans=0;
for (int i=1;i<pre.size();i++)
for (int j=0;j<back.size()-1;j++)//注意pre和back的判斷起始位置
if (pre[i]==back[j]&&pre[i-1]==back[j+1])ans++;
cout<<(1<<ans)<<endl;
return 0;
}