剑指 Offer 33. 二叉搜索树的后序遍历序列

262 阅读2分钟

这是我参与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

image.png

解题思路

  1. 利用搜索二叉树后序遍历的性质,数组的最后一个节点就是当前二叉树的根节点,数组前面的若干个元素必定来自于左子树,所以元素的值一定小于或等于根节点的值,数组后面的若干个元素必定来自于右子树,所以元素的值一定大于或等于根节点的值
  2. 如果满足二叉搜索树的话,通过遍历数组,我们必定可以将数组划分左右子树,并且元素的值必定都满足与根节点的大小关系,通过递归进行检验。

例如 [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);
    }
}