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

输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回 true,否则返回 false。假设输入的数组的任意两个数字都互不相同。

参考以下这颗二叉搜索树:

     5
    / \
   2   6
  / \
 1   3

示例 1:

输入: [1,6,3,2,5]
输出: false
示例 2
输入: [1,3,2,6,5]
输出: true

题解

  1. 首先我们知道的是后续遍历是左、右、根的顺序,而二叉搜索树的性质是中序遍历得到的是从小到大的一个序列!千万不要固定思维,我们这么考虑
  2. 按照二叉树的性质:左子树的节点小于根,右子树的节点大于根,而后序是最后遍历根,那么我们可以得出这个数组的最后一个元素是整个二叉树的根!
  3. 由这个结论我们延伸出另一个结论,数组的前一部分是左子树肯定小于根,而紧挨着的另一部分都大于于根!
    在这里插入图片描述

我们通过数组遍历的方式能不能找出第一个大于根节点的点?
这个点就定为索引为m的点!我们知道数组的长度为size() , 那么左右边界分别为【0,size() - 1】;
由此我们是否就能得出

  • [0,m-1] 表示左子树
  • [m,size()-2]表示右子树
  • size()-1表示根节点

接下来就是可以通过代码理解了!

//递归
class Solution {
public:
    bool verifyPostorder(vector<int>& postorder) {
        return recure(postorder, 0, postorder.size() -1 ) ;
    }
    bool recure(vector<int> postorder ,int l , int r){
        if(l >= r) return true ;  //长度为0数组为空
        int p = l ; //初始化p从左开始
        while(postorder[p] < postorder[r]) p ++ ;  //直到第m个节点大于根节点
        int m = p ; //右子树开始位置
        while(postorder[p] > postorder[r]) p ++ ; //直到存在不大于根的或者p走到根了
        return p == r && recure(postorder,l,m-1) && recure(postorder,m,r - 1) ;
    }
};
posted @ 2022-01-23 20:35  爪洼ing  阅读(22)  评论(0编辑  收藏  举报