题要
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。
难点
- 单支树输入:{1,2,3,4,5}
- 对于仅有单孩子节点的
递归分治
解法一
一
递归出口:
- 有单个子节点或无子节点 :r - l <= 1, 则return true
- 右子树区间内的所有节点都应大于根节点,否则return false
class Solution {
public boolean verifyPostorder(int[] postorder) {
int l = postorder.length;
if(l==0) return true;
return recur(postorder, 0, postorder.length-1);
}
public boolean recur(int[] postorder, int l, int r){
if (r - l <= 1) return true;//注意输出条件为r - l <= 1,可能有单个子节点也有可能有无子节点
int f = l;
while(f<r&&postorder[f]<postorder[r]){//对于{1,2,3,4}的输入,则循环结果为f==r
f++;
}
for(int j=f; j<r; j++){//false的判定条件,对于f==r则不会进行此循环
if(postorder[j]<postorder[r]){
return false;
}
}
return recur(postorder, l, f-1)&&recur(postorder, f, r-1);
}
}
解法二
递归出口:
- 若无子节点则i>j;若有单个子节点则i==j
- 每一层递归中是否从头遍历到尾
class Solution {
public boolean verifyPostorder(int[] postorder) {
return recur(postorder, 0, postorder.length - 1);
}
boolean recur(int[] postorder, int i, int j) {
if(i >= j) return true;//
int p = i;
while(postorder[p] < postorder[j]) p++;
int m = p;
while(postorder[p] > postorder[j]) p++;//检测是否右子树区间是否符合条件
return p == j && recur(postorder, i, m - 1) && recur(postorder, m, j - 1);
//若p!=j即右子树有不符合二叉搜索树条件的节点
}
}