【编程-剑指offer】二叉搜索树的后序遍历序列

根据输入的整数数组,判断是否为某二叉搜索树的后序遍历结果。后序遍历特点是序列最后为根节点,前部分可分解为左子树(所有元素小于根节点)和右子树(所有元素大于根节点)。解题方法包括递归和非递归,通过对比序列划分及验证左右子树满足条件来判断。

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

题目:

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

解题思路:

       1. 二叉搜索树:左子树永远比右子树小

       2. 后序遍历:最后访问根节点

由上述两点可知:后序遍历序列的最后是根节点,可以将前面的部分分为比它小的左子树和比它大的右子树。

1、递归:

          这道题很显然我们可以用递归的方法来做:只要我们判断当前序列的最后节点,可以将前面序列可以完全分解为左子树序列和右子树序列,并且这两个序列也满足这样的条件,那个这个序列就是正确的。

1)找到序列的最后一个元素a

2)判断a能否将序列完全分解成左子树序列和右子树序列

i = 0;

while(seq[i]<a)压入左子树;i++;

while(seq[i]>a)压入右子树;i++;

if(左子树+右子树=序列的长度 && 左子树满足条件 && 右子树满足条件)return true;

return false;

代码:

        这里我采用的方法是用两个vector<int>数组来存储左子树和右子树,大家也可以采用记录左右子树开始和结束的索引的方法,将这两个索引值作为函数参数传入,这样可以节省存储空间。

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        if(sequence.size()==0)return false;
        return isSquenceOfBST(sequence);
    }
    bool isSquenceOfBST(vector<int> sequence){
        if(sequence.size()==1 || sequence.size()==0)return true;
        int a = sequence[sequence.size()-1];
        int i=0;
        vector<int> left;
        vector<int> right;
        while(sequence[i]<a){
            left.push_back(sequence[i]);
            ++i;
        }
        
        while(sequence[i]>a){
            right.push_back(sequence[i]);
            ++i;
        }
        if(left.size()+right.size() == sequence.size()-1)
            if(isSquenceOfBST(left) && isSquenceOfBST(right))
                return true;
        return false;
    }
    
};

2、非递归: 

非递归其实也使用了类似的思想。

          每个序列的最后一个值一定是可以把前面的序列划分为左右子树的。

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int size = sequence.size();
        if(size==0)return false;
        
        while(size--){
            int i=0;
            while(sequence[size]>sequence[i]){i++;}
            while(sequence[size]<sequence[i]){i++;}
            if(i!=size)return false;
        }
        return true;
    }  
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值