输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
class Solution {
public:
/*
二叉搜索树后序遍历特点:最后一个数字是树的根节点的值。数组中前面两部分的数字可以分为两部分:
第一部分是左子树节点的值,他们都比根节点的值小;第二部分是右子树节点的值,他们都比根节点的值大。
所以本题可以考虑用递归解答。
*/
bool VerifySquenceOfBST(vector<int> sequence) {
int len = sequence.size();
if (len <= 0||sequence.empty())
return false;
return VerifyLeftAndRightSequenceOfBST(sequence, 0, len - 1);
}
/*
注意将数组分左右部分时不能简单地取中值,因为二叉搜索树可能不对称,例如说4,6,7,5这类,
其左子树只有一个节点,右子树有两个节点。所以更准确的方法是遍历列表,找到第一个大于根节点的即为右半部分起始点。
以这个点分开左右部分。
另外,退出循环的条件start>=end;这是根绝实际条件判断的。仅仅是等于还不足以概括所有情况。例如当一个根没有左子树只有右子树时。
*/
//取出数组单独一截进行遍历,判断是否符合条件
bool VerifyLeftAndRightSequenceOfBST(vector<int> sequence, int start, int end)
{
if (start >= end)
return true;
//int mid = (start + end) / 2;
//根节点即数组最后一位
int rootValue = sequence[end];
//遍历节点,找到左右节点的分界点
int i = start;
for (; i < end; i++)
{
if (sequence[i] > rootValue)
break;
}
int mid = i;
//遍历后面一部分节点,判断是否全部大于根节点值。若否,退出
for (int i = mid; i < end; i++)
{
if (sequence[i] <= rootValue)
return false;
}
return VerifyLeftAndRightSequenceOfBST(sequence, start, mid - 1)
&& VerifyLeftAndRightSequenceOfBST(sequence, mid, end - 1);
}
};