剑指 Offer 33. 二叉搜索树的后序遍历序列
题目描述
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
解答
class Solution {
/**
递归分治:
根据二叉搜索树的定义,可以通过递归,判断所有子树的正确性(即其后序遍历是否满足二叉搜索树的定义),
若所有子树都正确,则此序列为二叉搜索树的后序遍历
递归解析:
终止条件:当 i>=j,说明此子树节点数量≤1,无需判断正确性,因此直接返回true;
递推工作:
划分左右子树:
遍历后续遍历的[i,j]区间元素,寻找第一个大于根节点的节点,索引记为m。
此时,可划分出左子树区间[i,m-1]、右子树区间[m,j-1]、根节点索引j
判断是否为二叉搜索树:
左子树区间[i,m-1]内的所有节点都应 < postorder[j]。而“划分左右子树”时已经保证
左子树区间的正确性,因此只需要判断右子树区间即可。
右子树区间[m,j-1]内的所有节点都应 > postorder[j]。实现方式为遍历,当遇到 ≤ postorder[j]
的节点则跳出;则可通过p == j判断是否为二叉搜索树
返回值:所有子树都需正确才可判定正确,因此使用与逻辑符&&链接
p == j:判断此树是否正确
isBSTree(i,m-1):判断左子树是否正确
isBSTree(m,j-1):判断右子树是否正确
*/
public boolean verifyPostorder(int[] postorder) {
return isBSTree(postorder,0,postorder.length-1);
}
public boolean isBSTree(int[] postorder,int i,int j){
if(i >= j){
return true;
}
int l = i;
while(postorder[l] < postorder[j]){
l++;
}
int m = l;
int p = m;
while(postorder[p] > postorder[j]){
p++;
}
if(p != j){
return false;
}else{
return isBSTree(postorder,i,m-1) && isBSTree(postorder,m,j-1);
}
}
}