剑指offer23_二叉搜索树的后序遍历序列
二叉搜索树的后序遍历序列
题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。
示例1
输入
[4,8,6,12,16,14,10]
返回值
true
分析
方案一:递归分治
/**
时间复杂度 O(N^2)
每次调用 recur(i,j) 减去一个根节点,因此递归占用 O(N) 最差情况下(即当树退化为链表),每轮递归都需遍历树所有节点,占用 O(N)。
空间复杂度 O(N) : 最差情况下(即当树退化为链表),递归深度将达到 N 。
**/
class Solution
{
public:
bool recur(vector<int> postorder, int i, int j)
{
// 当i>=j,说明此子树节点数量<=1,无需判断正确性,直接返回true
if (i >= j)
return true;
int p = i;
//左子树区间[i,m-1]
while (postorder[p] < postorder[j])
p++;
//划分左右子树,第一个大于根节点的节点索引记为m
int m = p;
// 右子树区间[m,j-1]
while (postorder[p] > postorder[j])
p++;
// p == j来判断是否为二叉搜索树
return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
}
bool verifyPostorder(vector<int> postorder)
{
return recur(postorder, 0, postorder.size() - 1);
}
};
方案二:辅助单调栈
/**
时间复杂度 O(N) : 遍历 postorder 所有节点,各节点均入栈 / 出栈一次,使用 O(N) 时间。
空间复杂度 O(N) : 最差情况下,单调栈 stack 存储所有节点,使用 O(N) 额外空间。
**/
class Solution
{
public:
bool VerifySquenceOfBST(vector<int> sequence)
{
stack<int> st;
int root = INT_MAX;
for (int i = sequence.size() - 1; i >= 0; i--)
{
// 若 ri > root,说明此后序遍历序列不满足二叉搜索树定义,直接返回 false;
if (sequence[i] > root)
return false;
// 当栈不为空 且 ri < stack.top()时,循环执行出栈,并将出栈节点赋给 root
while (!st.empty() && st.top() > sequence[i])
{
root = st.top();
st.pop();
}
// 将当前节点 ri入栈
st.push(sequence[i]);
}
// 若遍历完成,则说明后序遍历满足二叉搜索树定义,返回 true
return true;
}
};