[劍指offer]二叉搜索樹的後序遍歷數列
題目描述
輸入一個整數數組,判斷該數組是不是某二叉搜索樹的後序遍歷結果。如果是則返回 true,否則返回 false。假設輸入的數組的任意兩個數字都互不相同。
參考以下這顆二叉搜索樹:
5
/ \
2 6
/ \
1
示例 1:
輸入: [1,6,3,2,5]
輸出: false
示例 2:
輸入: [1,3,2,6,5]
輸出: true
提示:
數組長度 <= 1000
解題思路
- 二叉搜索樹特點:若它的左子樹不爲空,則左子樹上所有節點的值均小於它的根節點的值;若它的右子樹不爲空,則右子樹上所有節點的值均大於它的根節點的值。
- 後序遍歷序列的最後一個值爲二叉樹的根節點,前面分爲兩部分,前半部分都小於根節點的值,後半部分都大於根節點的值。
- 假設後序遍歷序列長度爲len,最後一個值爲root,找出序列中第一個大於root的值的位置i,那麼[0,i)爲它的左子樹,[i,len)爲它的右子樹。
實現代碼
class Solution {
public:
bool verifyPostorder(vector<int>& postorder) {
int len = postorder.size();
if(len==0)
return true;
int root = postorder[len-1];//根節點的值
vector<int> left;
vector<int> right;
int temp=0;
for(int i=0;i<len-1;i++){//得到左子樹序列
temp=i;//保存第一個大於root值的位置
if(postorder[i]<root)
left.push_back(postorder[i]);//左子樹
else//找到了第一個大於root的值,temp保存了它的位置
break;
}
if(temp==len-2)//說明左邊的值都小於root,沒有右子樹
temp=temp+1;
for(int i=temp;i<len-1;i++){//得到右子樹序列
if(postorder[i]<root)//如果[temp,len-1)中有小於root值得,返回flase
return false;
right.push_back(postorder[i]);//右子樹
}
if(verifyPostorder(left)&verifyPostorder(right))//遞歸,判斷左子樹和右子樹是否都符合二叉搜索樹條件
return true;
return false;
}
};