剑指offer(C++)-JZ33:二叉搜索树的后序遍历序列(数据结构-树)

简介: 剑指offer(C++)-JZ33:二叉搜索树的后序遍历序列(数据结构-树)

题目描述:

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


数据范围: 节点数量 0≤n≤1000 ,节点上的值满足 1≤val≤105 ,保证节点上的值各不相同

要求:空间复杂度 O(n),时间时间复杂度 O(n^2)


提示:


1.二叉搜索树是指父亲节点大于左子树中的全部节点,但是小于右子树中的全部节点的树。


2.该题我们约定空树不是二叉搜索树


3.后序遍历是指按照 “左子树-右子树-根节点” 的顺序遍历


4.参考下面的二叉搜索树,示例 1

示例1:

输入:

[3,1,2]


返回值:

false

说明:

不属于上图的后序遍历,从另外的二叉搜索树也不能后序遍历出该序列 ,因为最后的2一定是根节点,前面一定是孩子节点,可能是左孩子,右孩子,根节点,也可能是全左孩子,根节点,也可能是全右孩子,根节点,但是[3,1,2]的组合都不能满足这些情况,故返回false  

示例2:

输入:

[5,7,6,9,11,10,8]


返回值:

true

解题思路:

本题考察数据结构树的使用。两种解法:


1)递归法。二叉树的后序遍历顺序是左右根,最后一个结点是根,往前大于根值的都是右子树的范畴,再往前小于根植的都是左子树。基于上述逻辑,可以拆解左右子树,再对左右子树分别检查,直到最深层完成,再一层层返回结果,完毕。


2)模拟检验法(栈)。二叉搜索树的中序遍历序列和从小到大排序序列一致,因此可以快速获取中序遍历序列;将中序遍历序列入栈,模拟后序遍历序列的出栈行为,若合理,则说明是二叉搜索树的后续遍历结果。

测试代码:

解法一:递归法

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        int size=sequence.size();
        if(size==0)
            return false;
        return check(sequence,0,size-1);
    }
    bool check(vector<int> sequence, int start, int end)
    {
        // 当start和end重合,返回true
        if(start>=end)
            return true;
        // 获取根结点
        int root=sequence[end];
        // 获取右子树
        int j=end-1;
        while(j>=0&&sequence[j]>root)
            j--;
        // 分析左子树
        for(int i=start;i<=j;++i)
        {
            if(sequence[i]>root)
                return false;
        }
        // 左右子树分别检查
        return check(sequence,start,j)&&check(sequence,j+1,end-1);
    }
};

解法二:模拟检验法(栈)

class Solution {
public:
    bool VerifySquenceOfBST(vector<int> sequence) {
        if(sequence.empty()) 
            return false;
        // 获取中序遍历序列
        // 二叉搜索树的中序遍历序列和其从小到大排序结果一致
        vector<int> midorder(sequence);
        sort(midorder.begin(), midorder.end());
        // 模拟中序遍历和后续遍历,验证所对应的二叉搜索树是否一致
        return getResult(midorder, sequence);
    }
    bool getResult(vector<int> midorder,vector<int> sequence) {
         int s = midorder.size();
         // 定义栈
         stack<int> temp;
         int i = 0, j = 0;
         // 遍历midorder(中序遍历序列)
         while(i < s)
         {
             // 将中序遍历序列的值依次入栈
             temp.push(midorder[i]);
             // 模拟后序遍历序列的出栈序列
             while(!temp.empty() && temp.top() == sequence[j])
             {
                 ++j;
                 temp.pop();
             }
             ++i;
         }
        // 判断是否匹配
         return j == s;
     }
};


相关文章
|
1月前
|
存储 算法 C++
【C/C++ 数据结构 】无向图和有向图的差异
【C/C++ 数据结构 】无向图和有向图的差异
25 0
|
1天前
|
算法
数据结构与算法-AVL树入门
数据结构与算法-AVL树入门
6 0
|
1天前
|
算法
数据结构与算法-Trie树添加与搜索
数据结构与算法-Trie树添加与搜索
5 0
|
10天前
|
算法 DataX
二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”
二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”
|
1月前
|
存储 算法 程序员
【数据结构】【版本2.0】【树形深渊】——二叉树入侵
【数据结构】【版本2.0】【树形深渊】——二叉树入侵
|
1月前
|
算法 C++ 开发者
【C/C++ 数据结构 】二叉树基本性质:具有n个结点的完全二叉树的深度为[log2n]+1或者[log2(n+1)]...
【C/C++ 数据结构 】二叉树基本性质:具有n个结点的完全二叉树的深度为[log2n]+1或者[log2(n+1)]...
12 0
|
1月前
|
存储 算法 数据库
【C/C++ 数据结构 】树的 四种表示方法
【C/C++ 数据结构 】树的 四种表示方法
30 0
|
1月前
|
存储 算法 C语言
【C/C++ 数据结构 树】探索C/C++中的二叉树:从理论到实践
【C/C++ 数据结构 树】探索C/C++中的二叉树:从理论到实践
60 0
|
1月前
|
存储 设计模式 算法
【C/C++ 数据结构 线性表】深入理解与实现栈:从基础到应用的全面探索
【C/C++ 数据结构 线性表】深入理解与实现栈:从基础到应用的全面探索
53 0
|
6天前
|
存储 编译器 C语言
c++的学习之路:5、类和对象(1)
c++的学习之路:5、类和对象(1)
21 0