題意:輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷的結果。如果是則輸出Yes,否則輸出No。假設輸入的數組的任意兩個數字都互不相同。
分析:判斷一個序列是否是二叉搜索樹的後序遍歷,首先由二叉搜索樹的性質得知,二叉搜索樹的左子節點都比父親要小,而右子節點都比父親要大,這時結合後序遍歷的特點:左右根,所以我們的策略就是:首先得到一個序列中最後一個元素,當作根,那麼接下來尋找左右子樹的劃分區間,尋找大於當前根的第一個值,那麼以這個值爲劃分,找到了當前根的左右子節點範圍,接着進行判斷,看它的右子樹的值是否都能夠大於當前根的值,如果不能,那麼這個序列就返回false,如果可以,那麼遞歸向下判斷當前根的左右子樹是否滿足。
特別注意,遞歸邊界的正確性,不要把根設置到判斷的範圍,否則會造成程序崩潰。
//判斷一個序列是否是一個二叉搜索樹的後序遍歷結果
//首先找到根節點,接着根據二叉搜索樹的性質劃分左右子樹,遞歸判斷左右子樹
class Solution {
public:
Solution()
{
}
~Solution()
{
}
bool judge(vector<int>vec,int l,int r)
{
if(r-l+1<=2) return true;
//根節點值
int temp = vec[r];
int i=l;
while(i<r) //注意邊界值
{
//找到劃分邊界
if(vec[i]>temp) break;
i++;
}
for(int j=i;j<r;j++)
{
if(vec[j]<=temp) return false;
}
//此時左右子樹均滿足要求 遞歸判斷左右子樹
bool left = true, right = true;
int leftLength = i-l , rightLength = r-i;
if(leftLength>0) {
left = judge(vec,l,i-1);
}
if(rightLength>0) {
right = judge(vec,i,r-1);
}
return (left&&right);
}
bool VerifySquenceOfBST(vector<int> sequence) {
int len = sequence.size();
if(len<=0) return false;
if(len<=2) return true;
return judge(sequence,0,len-1);
}
};