class Solution {
public:
bool verifyPostorder(vector<int>& postorder) {
// 后序遍历中倒数第一个结点为根节点root
// 如果是二叉搜索树的后序(根据左小右大,并且后序先左后右)
// 那么遍历结果存在一个拐点k,k之前都小于root,从k开始都大于root
// 如果从k开始到root之前的结点,存在小于root的结点,那就返回false
return dfs(postorder, 0, postorder.size()-1);
}
bool dfs(vector<int>& postorder, int l, int r){
if(l>=r) return true; // 只有一个结点返回true
// 可以演绎一下[5,4,3,2,1] 没有左子树的情况,应该要返回true
// 拐k=0, 之后左子树[0, -1] 应该要返回true。如果返回false答案就错了
int k = l;
int root = postorder[r]; // 倒数第一个结点为根
while(postorder[k]<root) // 从第一个结点开始,找到拐点
k++;
// 此时postorder[k]>root,遍历完剩下的结点,检查是否有小于root的
// 如果有,说明不满足,返回false
for(int i=k; k<r; k++){
if (postorder[k]<root)
return false;
}
// 没有返回false说明该区间满足(k之前小,k之后大)
// 但是我们要进一步检查左右子树是否也满足 左子树[l, k-1] 右子树[k+1, r]
return dfs(postorder, l, k-1) && dfs(postorder, k+1, r);
}
};
剑指 Offer 33. 二叉搜索树的后序遍历序列
最新推荐文章于 2024-10-05 15:48:11 发布