题目
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true
,否则返回 false
。假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:
5
/ \
2 6
/ \
1 3
示例 1:
输入: [1,6,3,2,5]
输出: false
示例 2:
输入: [1,3,2,6,5]
输出: true
提示:
数组长度 <= 1000
解题思路
1.题目要求我们判断所给数组是不是某二叉搜索树的后序遍历结果,我们使用递归来实现。
2.首先我们观察一下正确的二叉搜索树的后序遍历的结果,
举个例子:
对于上面给出的二叉搜索树,我们可以观察到在遍历结果中根节点在最后一位,因此我们可以轻松的找到根节点root(6)。
因为二叉搜索树有一个特性就是根节点的左孩子都小于根节点,根节点的右孩子都大于根节点。因此当我们找到第一个大于根节点的元素时(7),就意味着我们找到了左右孩子的分界点。第一个大于根节点的元素之前 [3,4,5] 是根节点的左孩子,剩下的元素除了我们找到的最后一位是根节点,其余的都是根节点的右孩子 [7,8,9]。
这个时候我们就要判断所给数组是否为正确,我们需要从找到的第一个大于根节点的元素,也就是 7 开始,判断除去根节点的后面的元素 [7,8,9] 中是否存在有小于根节点的元素。因为我们知道从7开始都是属于根节点的右子树肯定都是大于根节点的元素。若存在小于根节点的元素,那么就说明这个数组是有误的,我们就要返回false。
当检查没有问题时,我们就需要递归得去判断6的左右子树是否正确,我们将左右子树传入递归函数中,左子树 [3,5,4] 的最后一个元素依旧是根节点(4),然后找到第一个大于根节点的元素(5),判断从此元素(5)开始向后遍历到根节点(4)的前一个元素是否有元素小于根节点(4),若没有就继续递归,直到所有元素都遍历结束。
代码实现
class Solution {
public boolean verifyPostorder(int[] postorder) {
if(postorder == null){
return true;
}
return f(postorder, 0, postorder.length - 1);
}
boolean f(int[] postorder, int i, int j){
if(i >= j){
return true;
}
int root = postorder[j];
int p = i;
//获取第一个大于等于root的元素
while(postorder[p] < root) p++;
for(int k = p; k < j; k++){
//查找p ~ j - 1是否存在小于root的元素
if(postorder[k] < root){
return false;
}
}
return f(postorder, i, p - 1 ) && f(postorder, p, j - 1);
}
}
测试结果