这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
剑指 Offer 33. 二叉搜索树的后序遍历序列
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:
5
/ \
2 6
/ \
1 3
示例 1:
输入: [1,6,3,2,5] 输出: false 示例 2:
输入: [1,3,2,6,5] 输出: true
解题思路
- 利用搜索二叉树后序遍历的性质,数组的最后一个节点就是当前二叉树的根节点,数组前面的若干个元素必定来自于左子树,所以元素的值一定小于或等于根节点的值,数组后面的若干个元素必定来自于右子树,所以元素的值一定大于或等于根节点的值
- 如果满足二叉搜索树的话,通过遍历数组,我们必定可以将数组划分左右子树,并且元素的值必定都满足与根节点的大小关系,通过递归进行检验。
例如 [3,5,4,10,12,9]
我们知道后续遍历的最后一个数字一定是根节点,所以数组中最后一个数字9就是根节点,我们从前往后找到第一个比9大的数字10,那么10后面的[10,12](除了9)都是9的右子节点,10前面的所有节点都是9的左子节点,所以应该必须都要满足大于9,后面的需要遍历一次,如果有小于9的,说明不是二叉搜索树,直接返回false。然后再以递归的方式判断左右子树。
代码
class Solution {
public boolean verifyPostorder(int[] postorder) {
return verifyPostorder(postorder,0,postorder.length-1);
}
public boolean verifyPostorder(int[] postorder,int l,int r) {
if (r<=l) return true;
int root=postorder[r];
int i=l;
for (;i<r;i++)
if (postorder[i]>root)
break;
int tl=i;
for (;i<r;i++)
if (postorder[i]<root)
return false;
return verifyPostorder(postorder,l,tl-1)&&verifyPostorder(postorder, tl, r-1);
}
}