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

本文详细介绍了如何判断一个整数数组是否为二叉搜索树的后序遍历结果。通过理解二叉搜索树的性质和后序遍历顺序,采用分治策略,从大到小划分数组并递归检查左右子树,确保每个子树满足二叉搜索树的条件。代码实现中展示了具体的划分和检查过程,帮助读者深入理解这一算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

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

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

     5
    / \
   2   6
  / \
 1   3

示例:

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

解题思路

首先,要明确两个性质:

  1. 二叉搜索树,左子树节点最大值 < 根节点值 < 右子树节点最大值,且左、右子树亦为二叉搜索树;
  2. 后续遍历:数组内顺序为左、右、根。其中左、右可能为空、单节点、复数节点(嵌套左、右、根)。

因此,思路就很简单了:

  1. 根据后续遍历数组从大维度向小维度划分数组(左子树、右子树、根节点),即分治思想!
  2. 遍历检查,左子树所有节点数值应小于根节点,右子树所有节点数值应大于根节点。
  3. 递归第一步划分后的左右子树。

实现细节:

  • 划分子树,从右向左划分,最右边一定为根节点,遇到一个小于根节点值的节点前的子数组即为右子树,剩余为左子树;
  • 由于划分过程,右子树一定合法,因此只需检查左子树;
  • 返回结果需要左右子树都合法,因此使用 && 连接。

代码实现

class Solution {
public:
    bool verifyPostorder(vector<int>& postorder) {
        return dfs(postorder, 0, postorder.size());
    }

    bool dfs(vector<int>& postorder, int begin, int end){
        if(end - begin <= 1) return true;
        int temp = postorder[end - 1];
        int posi = end - 2;
        
        for(; posi >= 0; posi--){
            if(postorder[posi] < temp) break;
        }

        for(int i = posi; i >= 0; i--){
            if(postorder[i] > temp) return false;
        }

        return dfs(postorder, begin, posi + 1) && dfs(postorder, posi + 1, end - 1);
    }
};

运行结果:

在这里插入图片描述

使用单调栈可能性能上会有提升,这个我们以后再讲。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值