在衆多的數據結構中,二叉樹是一種特殊而重要的結構,有着普遍的應用。二叉樹或者是一個結點,或者有且僅有一個結點爲二叉樹的根,其他結點被分紅兩個互不相交的子集,一個做爲左子集,另外一個做爲右子集,每一個子集又是一個二叉樹。 ios
遍歷一棵二叉樹就是按某條搜索路徑巡訪其中每一個結點,使得每一個結點均被訪問一次,並且僅被訪問一次。最常使用的有三種遍歷的方式: 數據結構
1.前序遍歷:若二叉樹爲空,則空操做;不然先訪問根結點,接着前序遍歷左子樹,最後再前序遍歷右子樹。 函數
2.中序遍歷:若二叉樹爲空,則空操做;不然先中序遍歷左子樹,接着訪問根結點,最後再前中遍歷右子樹。 spa
3.後序遍歷:若二叉樹爲空,則空操做;不然前後序遍歷左子樹,接着後序遍歷右子樹,最後再訪問根結點。 code
例如圖(1)所示的二叉樹: orm
前序遍歷的順序是ABCD,中序遍歷的順序是CBAD,後序遍歷的順序是CBDA。 ip
對一棵二叉樹,若是給出前序遍歷和中許遍歷的結點訪問順序,那麼後序遍歷的順序是惟一肯定的,也很方便地求出來。但若是如今只知道前序遍歷和後序遍歷的順序,中序遍歷的順序是不肯定的,例如:前序遍歷的順序是ABCD,然後序遍歷的順序是CBDA,那麼就有兩課二叉樹知足這樣的順序(見圖(1)和圖(2))。 ci
如今的問題是給定前序遍歷和後序遍歷的順序,要求出總共有多少棵不一樣形態的二叉樹知足這樣的遍歷順序。 string
ABCD CBDA
2
能夠這麼考慮,當且僅當以節點爲根的子樹(或原樹)子節點只有一個,會產生多種解的狀況。那麼明顯,僅僅根據前序和後序遍歷的結果,單個的子節點沒法肯定左右位置。能夠判斷有n個這樣的節點,那麼就可能有2^n種生成樹。而這樣的節點在本題中的明顯特徵就是,對應前序遍歷路徑中的特定節點,它的右面相鄰的節點和後序遍歷中此節點的左面相鄰節點相同。最後注意,利用string的成員函數find()能夠節省不少時間。 it
ps:本題還有另外的表示方法,即直接比較對應字符,不過這裏採用別人的一種解法,更有意思也更能體會二叉樹遍歷的特色。
// Problem#: 1210 // Submission#: 1860874 // The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License // URI: http://creativecommons.org/licenses/by-nc-sa/3.0/ // All Copyright reserved by Informatic Lab of Sun Yat-sen University #include <iostream> #include <string> using namespace std; int main(){ string str1,str2; int re = 1; cin >> str1 >> str2; int size = str1.size(); int tmp = size - 1; for( int i=1 ; i<size ; i++ ){ int j = str2.find(str1[i]); if( j==tmp-1 ) re *= 2; tmp = j; } cout << re; return 0; }