题目:
输入一个整数数组 treePT, 判断该数组是不是某二叉搜索树的后序遍历结果. 如果是返回 true, 否则返回 false.
示例
输入数组: 5, 7, 6, 9, 11, 10, 8
返回: true
输入数组: 7, 4, 8, 5
返回: false
问题解析
二叉搜索树必然有以下结论成立:
- 左子树上任意节点的值必然小于父结点的值;
二叉搜索树的后序遍历的性质 (由右向左):
- 局部递减 ( 由右向左 ) 序列的最小值为左子树根节点的值;
- 当前最小值 ( 由右向左的最小值 ) 左边的所有结点是该最小值结点的所有子孙结点.
算法:
- [ 初始化 ] 置
itr = N - 1, min = treePT[itr], min2th = min
, 判断是否为空, 是结束算法, 否则实施步骤 2; - [ 对 itr 进行循环 ]
itr = N - 1, N - 2, ..., 1
, 找到 ( 数组由后向前 ) 最长递增序列, 赋最大值 + 1 给min2th
, 实施步骤 3; - [ 继续循环, 比较 itr : 0 ] 若
itr >= 0
实施步骤 4~6, 否则结束循环, 返回 true; - [ 比较 treePT[itr] : min2th ] 若
treePT[itr] >= min2th
结束算法, 返回 false; 否则实施步骤 5; - [ 比较 treePT[itr] : min ] 若
treePT[itr] > min
返回步骤 3; 否则实施步骤 6; - [ 更新 min, min2th ]
min2th = min, min = treePT[itr]
返回步骤 3.
该算法的时间复杂度为 O(N), 空间复杂度为 O(1).
基于上述结论及算法 C++ 代码实现如下,
#include <iostream>
#incldue <vector>
using namespace std;
struct myStack {
int len;
vector<int> stack;
struct myStack() {
len = 0;
}
};
bool isPostorderTraver(vector<int> treePT)
{
if (treePT.size() <= 0)
return false;
int itr = treePT.size() - 1;
int min = treePT[itr], // 左子树根结点的值
min2th = treePT[itr]; // 父结点的值
// 找到数组末尾递减序列的最大值, 即二叉树搜索树的最大值
while (itr > 0 && treePT[itr - 1] > treePT[itr]) itr--;
min2th = treePT[itr] + 1; // 虚拟 root 结点的父结点的值
for( ; itr >= 0; --itr)
{
// 左子树大于等于父结点, 返回 false
if (treePT[itr] >= min2th)
return false;
// 大于当前最小值, 不更新
if (treePT[itr] > min)
continue;
// 更新左子树根节点及其父节点的值
min2th = min;
min = treePT[itr];
}
return true;
}