LeetCode题解「 剑指 Offer 33 」:二叉搜索树的后序遍历序列

题目描述: 

        输入一个整数数组,判断该数组是否为某二叉搜索树后序遍历序列,是则返回true,否则返回false,输入的数组中任意两数互不相同

解题核心:

        二叉搜索树的左子树所有结点的值都比根结点右子树所有结点的值都比根结点

解题思路:

        以下列二叉树为例:

       该二叉树的后序遍历序列为:

1(左子树)

3(左子树)

2(左子树)

6(右子树)

5(根节点)

       二叉树后序遍历的特性为:[ 左子树 | 右子树 | 根节点 ],由于二叉搜索树的左子树中的任意结点的值比根节点的值右子树中的任意结点值比根节点的值,我们可以得知,一个正确的二叉搜索树后序遍历序列中,序列的最后一项一定是根节点对应的值,再从左往右遍历序列,找到第一个比最右侧元素(根节点对应元素)的值大的元素,这个元素便是右子树的一部分,而从序列最左侧元素到这个元素的前一个元素形成的序列便是左子树的序列,这个元素开始直到根节点的前一个元素形成的序列便是右子树的序列。

       由于二叉树本身的结构特点,二叉树是一个天然适合使用分治法解决问题的数据结构,本题也是如此,在划分左右子树的序列以后递归操作判断。

函数设计:

返回类型:

        bool

参数:

        int beginIndex,序列第一个元素的索引。

        int root,当前树的根节点(最后一个元素的索引)。

        vector<int> tree,待检验的序列。

递归出口:

        当子树的序列的第一个元素索引大于等于根节点元素索引时说明该子树的结点数量不大于1,说明该子树合法,返回true。

        while循环遍历,找到当前序列中第一个比根结点元素值大的元素索引(若无该元素,将会找到根节点的前一个元素,接下来的for循环也不会进行)。再用for循环,从刚刚找到的索引出发,一直遍历到根节点,若找到一个值比根节点元素的元素则说明当前序列不是二叉搜索树的后序遍历,返回false。

递归实现:

        通过返回值来判断左右子树对应的序列的合法性,由于左右子树都应满足该规则,故两个递归函数之间应以&&连接。

代码实现:

        C++:

bool search(int beginIndex,int root,vector<int> tree)
{
    //若起始点大于根的位置则说明该子树的节点个数<=1,返回true
    if(beginIndex >= root)
        return true;

    //找到除根以外的第一个最大值
    int rightChildIndex = beginIndex;
    while(rightChildIndex < root && tree[rightChildIndex] < tree[root])
        rightChildIndex ++;

    //从右子树的起点开始寻找,若找到比根节点小的值返回false
    for(int i = rightChildIndex ; i < root ; i++)
        if(tree[i] < tree[root])
            return false;

    //通过返回来递归查找左右子树
    return search(beginIndex,rightChildIndex - 1,tree) && search(rightChildIndex,root - 1,tree);
}

 本题出处:

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值