有关剑指offer题目的解析:剑指offer 题目整理
题目要求
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
解题分析
首先你需要知道什么是二叉搜索树?
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树,BST)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。(百度百科)
然后,我们就根据根节点(由于是后序遍历,所以就是数组的最后一个元素)划分左右子树,分别判断是否符合BST的要求,最后递归的去遍历判断左右子树即可。
具体步骤:
1、确定root;
2、遍历序列(除去root结点),找到第一个大于root的位置,则该位置左边为左子树,右边为右子树;
3、遍历右子树,若发现有小于root的值,则直接返回false;
4、分别判断左子树和右子树是否仍是二叉搜索树(即递归步骤1、2、3)。
主要代码c++
加了一些注释便于理解
class Solution {
public:
bool VerifySquenceOfBST(vector<int> sequence) {
int size = sequence.size();
if(0==size)
return false;
vector<int>leftSequence,rightSequence;
int root = sequence[size-1];
// 划分左子树
// 如果遇到大于根节点的时候说明已经划分完毕
int i = 0;
for(i; i < size - 1; ++i) // - 1的原因是抛出去根节点
{
if(sequence[i] > root)
break;
else
leftSequence.push_back(sequence[i]);
}
// 划分右子树
// 如果遇到小于根节点的时候说明不符合BST的规则
// 里应根据上面左子树的划分,所有小于根结点的值都在左子树
for(int j = i;j < size - 1; ++j)
{
if(sequence[j] < root)
return false;
else
rightSequence.push_back(sequence[j]);
}
bool left = true;
if(!leftSequence.empty())
left = VerifySquenceOfBST(leftSequence); // 如有左子树 对左子树也进行同样的检查
bool right = true;
if(!rightSequence.empty())
right = VerifySquenceOfBST(rightSequence); // 如有右子树 对右子树也进行同样的检查
return left && right;
}
};
总结
本题主要考察大家对二叉搜索树的性质理解以及处理树的遍历序列的能力。
如果面试题需要处理一棵二叉树的遍历序列,则可以先找到二叉树的根节点,在基于根节点把二叉树的遍历序列拆分成基于左子树对应的子序列和右子树对应的子序列,然后递归处理整两个子序列即可。如【剑指offer】 面试题7 重建二叉树
另外在如何构建左右子树的时候也思考了一会,只要符合条件push相应的元素即可,本题也可以改成基于前序序列的的BST,那我们只要把根节点改成起始元素就可以套用本题的解法,要学会举一反三地能力哦~