一、需求

  • 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果,如果是则返回 true,否则返回 false
  • 假设输入的数组的任意两个数字都互不相同。
参考以下这颗二叉搜索树:5/ \2   6/ \1   3
示例 1:输入: [1,6,3,2,5]
输出: false
示例 2:输入: [1,3,2,6,5]
输出: true

二、分治算法

2.1  思路分析

  • 后序遍历:左、右、根。
  • 二叉搜索树:左子树中所有结点的值 < 根结点的值,右子树中所有结点的值 > 根结点的值,其左、右子树也分别为二叉搜索树。
  • 根据二叉树搜索树的定义,可以通过递归判断所有子树的正确性(即其后序遍历是否满足二叉搜索树的定义),若所有子树均正确,则此序列为二叉搜索树的后序遍历。

2.2  算法流程

  • 终止条件:当 i >= j,说明此子树结点数量 <= 1,无需判别正确性,因此直接返回true;
  • 递推工作:

1.划分左右子树:遍历后序遍历的[i, j]区间元素,寻找第一个大于根结点的结点,索引记为m,此时,可划分出左子树区间[i,m-1],右子树区间[m,j-1],根结点索引为 j 。

2.判断是否为二叉搜索树:

1.左子树区间[i,m-1]内的所有结点都应 < posterOrder[ j ] 。而在划分左右子树的步骤中,已经保证了左子树区间的正确性,因此,只需要判断右子树区间即可。

2.右子树区间[m,j-1]内的所有结点都应 > posterOrder[ j ] 。实现方式为遍历,当遇到 <= posterOrder[ j ]的结点跳出,通过判断p == j判断是否为二叉搜索树。

  • 返回值:所有子树均正确才可判定正确,因此使用与逻辑符连接。

1.p == j:判断此树是否正确。

2.recur(i,m-1):判断此树的左子树是否正确。

3.recur(m,j-1):判断此树的右子树是否正确。

2.3  代码实现

class Solution {public boolean verifyPostorder(int[] postorder) {return recur(postorder,0,postorder.length - 1);}public boolean recur(int[] postorder,int i,int j) {if(i >= j) return true;int p = i;while(postorder[p] < postorder[j]) p++;int m = p;while(postorder[p] > postorder[j]) p++;return p == j && recur(postorder,i,m-1) && recur(postorder,m,j-1);}
}

2.4  复杂度分析

  • 时间复杂度为O(N^2),每次调用recur(i,j)要减去一个根结点,因此递归占用O(N),最差情况下(当树退化为链表),每轮递归都需要遍历树的所有结点,占用O(N)。
  • 空间复杂度为O(N),最差情况下(当树退化为链表),递归深度将达到N。

三、辅助单调栈

3.1  思路分析

  • 后序遍历倒序:[根结点 | 右子树 | 左子树],类似于先序遍历的镜像,即先序遍历为"根、左、右"的顺序,而后序遍历的倒序为"根、右、左"。
  • 设后序遍历倒序列表为,遍历此列表,设索引为,若为二叉搜索树,则有:

1.当结点值时,结点一定是结点的右子结点。

2.当结点值时,结点一定是某结点root的左子结点,且root为结点中值大于且最接近的结点。

  • 当遍历时遇到递减结点,若为二叉搜索树,则对于后序遍历倒序中结点右边的任意结点,必有结点。(结点只可能为以下两种情况:的左、右子树的各结点;②为root的父结点或更高层父结点的左子树的各结点。在二叉搜索树中,以上结点都应小于root。)
  • 遍历"后序遍历的倒序"会多次遇到递减结点,若所有的递减结点对应的父结点root都满足以上条件,则可判定为二叉搜索树。
  • 根据以上描述,考虑借助单调栈实现:

1.借助一个单调栈stack存储值递增的结点;

2.每当遇到值递减的结点,则通过出栈来更新结点的父结点root;

3.每轮判定和root的值的关系:

1.若,说明不满足二叉搜索树的定义,直接返回false;

2.若,说明满足二叉搜索树的定义,则继续遍历。

3.2  算法流程

  1. 初始化:单调栈stack,父结点值(初始值为正无穷大,可把树的根节点看为此无穷大节点的左孩子);
  2. 倒序遍历postorder:记每个结点为

1.判断:若,说明此后序遍历序列不满足二叉搜索树的定义,直接返回false;

2.更新父结点root:当栈不为空且时,循环执行出栈,并将出栈结点赋给root;

3.入栈:将当前结点入栈;

3.若遍历完成,说明后序遍历满足二叉搜索树的定义,返回true。

3.3  代码实现

class Solution {public boolean verifyPostorder(int[] postorder) {Stack<Integer> stack = new Stack<>();int root = Integer.MAX_VALUE;for(int i = postorder.length - 1; i >= 0; i--) {if(postorder[i] > root) return false;while(!stack.isEmpty() && stack.peek() > postorder[i]) {root = stack.pop();}stack.add(postorder[i]);}return true;}
}

3.4  复杂度分析

  • 时间复杂度为O(N),各结点均出\入栈一次;
  • 空间复杂度为O(N),最差情况下,单调栈所有结点。

四、参考地址

作者:Krahets

链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/solution/mian-shi-ti-33-er-cha-sou-suo-shu-de-hou-xu-bian-6/

二叉搜索树的后序遍历序列相关推荐

  1. 剑指offer:面试题33. 二叉搜索树的后序遍历序列

    题目:二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回 true,否则返回 false.假设输入的数组的任意两个数字都互不相同. 参考以下这颗二叉搜 ...

  2. [剑指offer] 二叉搜索树的后序遍历序列

    二叉搜索树的后序遍历序列 P157 题目:输入一个数组,判断这个数组是不是一个二叉搜索树的后序遍历的结果. solution:我们知道后序遍历序列的最后一个item是根节点,如果确实是二叉搜索树的后序 ...

  3. 剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列

    剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列2013-11-23 03:16 题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出 ...

  4. C#刷剑指Offer | 二叉搜索树的后序遍历序列

    [C#刷题]| 作者 / Edison Zhou 这是EdisonTalk的第289篇原创内容 我们来用之前学到的数据结构知识来刷<剑指Offer>的一些核心题目(精选了其中30+道题目) ...

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

    [LeetCode]剑指 Offer 33. 二叉搜索树的后序遍历序列 文章目录 [LeetCode]剑指 Offer 33. 二叉搜索树的后序遍历序列 package offer;public cl ...

  6. 剑指offer——二叉搜索树的后序遍历序列

    二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. 这里遇到的问题就是,传递的子数组怎 ...

  7. 剑指offer——面试题24:二叉搜索树的后序遍历序列

    剑指offer--面试题24:二叉搜索树的后序遍历序列 Solution1: 二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二 ...

  8. 剑指offer之二叉搜索树的后序遍历序列

    剑指offer之二叉搜索树的后序遍历序列 欢迎关注作者博客 简书传送门 题目 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个 ...

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

    剑指 Offer 33. 二叉搜索树的后序遍历序列 原始题目链接:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-hou-xu-bian- ...

  10. 23.二叉搜索树的后序遍历序列

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

最新文章

  1. lol服务器维护9月30,英雄联盟4月30日更新维护几点结束_4月30日LOL10.9版本停机维护结束时间_3DM网游...
  2. Jzoj5234 外星人的路径
  3. 解锁新姿势 | 如何用配置中心实现全局动态流控?
  4. 开源RefreshListView下拉刷新效果
  5. Qt中常用的QChar QByteArry QString数据类型转换方法
  6. isset、empty、var==null、is_null、var===null详细理解
  7. js把base64串解析成中文_26日大嘴足球:晚场5中3/中2串+1比分,早场(意甲+西甲)2场解析!!...
  8. 网络摄像机 c++ 抓拍_IP摄像机和工业摄像机怎么区分 IP摄像机和工业摄像机差异...
  9. socket可读,可写的条件
  10. 电视盒子做文件共享服务器,【当贝市场】智能电视盒子和PC电脑文件共享教程...
  11. 个人征信要良好,申请信用卡需注意哪些事项?
  12. 量化交易1-backtrader介绍
  13. (附源码)php酒店住宿管理系统 毕业设计 261455
  14. 美团{青龙面板可跑项目之一}保姆教程
  15. C语言利用顺序表求两个集合的差集
  16. java(反射机制)
  17. 1323: 三角形判定
  18. 索罗斯:走在时间前面的狐狸
  19. Linux top命令的了解以及使用
  20. 《关键对话》如何高效沟通,营造无往不利的事业和人生?

热门文章

  1. H3C W2612 瘦AP转胖AP笔记本刷机教程
  2. MSER最稳定极值区域源码分析
  3. springboot整合IPDB,获取地区信息
  4. ssis抽MySQL数据_SSIS探索之SSIS增量抽取数据
  5. AES加解密之ECB、CBC和CFB三种模式
  6. php+大于的特殊符号,CSS_网页制作基础知识:html特殊符号,一些特殊符(如小于号和大于 - phpStudy...
  7. python - 截取指定帧数间隔的视频,并保存图片到指定位置
  8. 计算机网络-网络层篇-ARP协议与RARP协议
  9. 算法设计与分析入门篇----贪心法3
  10. C语言成绩管理系统实例 附源码(一)