题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
题目分析
二叉搜索树,又叫二叉排序树、二叉查找树:空树
,或左孩子小于等于根结点
且右孩子大于等于根结点
且左子树右子树均为二叉搜索树
。
后序遍历序列,最后一个数字为根root
,左半部分小于root
的为左子树,右半部分大于root
的为右子树。
要注意,左右子树都有可能为空,所以我们可以通过第一个数字和root
比较大小,来判断是否存在左子树。
判断是不是某二叉搜索树的后序遍历
:
0. 如果序列元素小于或等于1,返回真。
1. 找出根结点,即最后一个数字。
2. 根据数学关系找出左子树和右子树,如果序列中有数字剩下,说明当前序列不能分成左子树和右子树,返回假。
3. 递归调用此过程,如果左子树是某二叉搜索树的后序遍历
且右子树是某二叉搜索树的后序遍历
,返回真,否则返回假。
C++
class Solution
{
public:
bool VerifySquenceOfBST(vector<int> sequence)
{
return sequence.size() > 0 && VerifySquenceOfBST2(sequence);
}
bool VerifySquenceOfBST2(vector<int> sequence)
{
if (sequence.size() <= 1)
return true;
int root = sequence[sequence.size() - 1];
vector<int> left, right;
int i = 0;
if (sequence[0] < root) //存在左子树
{
for (; i < sequence.size() - 1 && sequence[i] < root; i++)
left.push_back(sequence[i]);
}
for (; i < sequence.size() - 1 && sequence[i] > root; i++)
right.push_back(sequence[i]);
if (i != sequence.size() - 1) //右子树不规范
return false;
return VerifySquenceOfBST2(left) && VerifySquenceOfBST2(right);
}
};
Java
import java.util.*;
public class Solution {
public boolean VerifySquenceOfBST(int[] sequence) {
return sequence != null && sequence.length > 0 && VerifySquenceOfBST2(sequence);
}
private boolean VerifySquenceOfBST2(int[] sequence) {
if (sequence.length <= 1)
return true;
int root = sequence[sequence.length - 1];
int index = 0, mid;
if (sequence[0] < root)// 有左子树
{
while (index < sequence.length - 1 && sequence[index] < root) {
index++;
}
}
mid = index;
while (index < sequence.length - 1 && sequence[index] > root) {
index++;
}
if (index != sequence.length - 1)// 右子树发生错误
return false;
return VerifySquenceOfBST2(Arrays.copyOf(sequence, mid))
&& VerifySquenceOfBST2(Arrays.copyOfRange(sequence, mid, sequence.length - 1));
}
}