二叉搜索树的后序遍历序列
JZ33 二叉搜索树的后序遍历序列
描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回 true ,否则返回 false 。假设输入的数组的任意两个数字都互不相同。
数据范围: 节点数量 $0≤n≤1000$ ,节点上的值满足 $1≤val≤105$ ,保证节点上的值各不相同
要求:空间复杂度 $O(n)$ ,时间时间复杂度 $O(n^2)$
提示:
1.二叉搜索树是指父亲节点大于左子树中的全部节点,但是小于右子树中的全部节点的树。
2.该题我们约定空树不是二叉搜索树
3.后序遍历是指按照 “左子树-右子树-根节点” 的顺序遍历
4.参考下面的二叉搜索树,示例 1
示例1
1 | 输入:[1,3,2] |
示例2
1 | 输入:[3,1,2] |
示例3
1 | 输入:[5,7,6,9,11,10,8] |
题解
初见思路:首先要想明白二叉搜索树的后序遍历有什么特点,最后一个一定是根节点,然后根据示例2我们可以想到一定能够找到一个位置,使得左侧的全部小于它,右侧的全部大于它。由此这就变成了一个数组问题,从最右侧找一个值,然后开始从左侧遍历,直到找到一个比它大的,记住这个位置,以此划分左右子树,从这里开始向右遍历,若是找到比它小的,则返回$false$,认定非法,若直到最后也找不到,则递归左右子树。
这道题目的坑在于空子树不算二叉搜索树,但是子树中的空子树我们应当视为二叉搜索树,在递归时需要注意。
代码
#include <vector>
#include <iostream>
using namespace std;
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
if(sequence.empty()) return false;
int length = sequence.size();
if(length == 1) return true;
int root = sequence[length-1];
int index = 0;
for(; index < length-1; index++){
if(sequence[index]>root) break;
}
int seperate = index;
for(;index<length-1;index++){
if (sequence[index]<root) {
return false;
}
}
vector<int> leftSeq;
for(int i = 0; i < seperate; i++) leftSeq.push_back(sequence[i]);
vector<int> rightSeq;
for(int i = seperate; i < length-1; i++) rightSeq.push_back(sequence[i]);
if (leftSeq.empty()) {
return VerifySquenceOfBST(rightSeq);
}else if (rightSeq.empty()) {
return VerifySquenceOfBST(leftSeq);
}else {
return (VerifySquenceOfBST(leftSeq) && VerifySquenceOfBST(rightSeq));
}
}
};