当前位置: 首页 > news >正文

面试题 33. 二叉搜索树的后序遍历序列

二叉搜索树的后序遍历序列

  • 题目描述
    • 示例
  • 题解
    • 递归
    • 单调栈

题目描述

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

示例

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

     5/ \2   6/ \1   3

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

题解

递归

后序遍历的最后一个元素为根节点,根据二叉搜索树的性质,根节点左边的元素都小于根节点,根节点右边的元素都大于根节点。因此,我们找到第一个大于根节点的位置 𝑖,那么 𝑖
右边的元素都应该大于根节点,否则返回 false。然后递归判断左右子树。

class Solution {
public:bool verifyPostorder(vector<int>& postorder) {function<bool(int, int)> dfs = [&](int l, int r) -> bool {if (l >= r) {return true;}int v = postorder[r];int i = l;while (i < r && postorder[i] < v) {++i;}for (int j = i; j < r; ++j) {if (postorder[j] < v) {return false;}}return dfs(l, i - 1) && dfs(i, r - 1);};return dfs(0, postorder.size() - 1);}
};

单调栈

后序遍历的顺序为“左、右、根”,如果从右往左遍历数组,那么顺序就变成“根、右、左”,根据二叉搜索树的性质,右子树所有节点值均大于根节点值。

因此,从右往左遍历数组,就是从根节点往右子树走,此时值逐渐变大,直到遇到一个递减的节点,此时的节点应该属于左子树节点。我们找到该节点的直接父节点,那么此后其它节点都应该小于该父节点,否则返回 false。然后继续遍历,直到遍历完整个数组。

此过程借助栈来实现,具体步骤如下:

  1. 首先初始化一个无穷大的父节点值 𝑚𝑥,然后初始化一个空栈。
  2. 接下来,从右往左遍历数组,对于每个遍历到的元素 𝑥
    • 如果 𝑥大于 𝑚𝑥,说明当前节点不满足二叉搜索树的性质,返回 false。
    • 否则,如果当前栈不为空,且栈顶元素大于 𝑥,说明当前节点为左子树节点,循环将栈顶元素出栈并赋值给 𝑚𝑥,直到栈为空或者栈顶元素小于等于 𝑥,然后将 𝑥入栈。
      遍历结束后,返回 true。
class Solution {
public:bool verifyPostorder(vector<int>& postorder) {stack<int> stk;int mx = 1 << 30;reverse(postorder.begin(), postorder.end());for (int& x : postorder) {if (x > mx) {return false;}while (!stk.empty() && stk.top() > x) {mx = stk.top();stk.pop();}stk.push(x);}return true;}
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • GD32 MCU上电跌落导致启动异常如何解决
  • 《简历宝典》18 - 简历中“技术能力”,如何丰满且有层次,Java篇
  • MySQL简介以及对数据库的操作
  • 力扣 102题 二叉树的层次遍历 记录
  • CSS 中border-radius 属性
  • 学习并测试SqlSugar的单库事务功能
  • k8s二次开发-kubebuiler一键式生成deployment,svc,ingress
  • Lamp 小白菜鸟从入门到精通
  • Git 用法
  • blender和3dmax和maya和c4d比较
  • 各类专业技术的pdf电子书
  • SmartX 超融合 vs vSAN 8:数据库场景下的性能对比
  • 塔子哥的快乐值-美团2023笔试(codefun2000)
  • 静态路由技术
  • 内存卡损坏读不出怎么修复?内存卡数据恢复的7个方法请收好!
  • 自己简单写的 事件订阅机制
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • avalon2.2的VM生成过程
  • C++类的相互关联
  • mac修复ab及siege安装
  • MD5加密原理解析及OC版原理实现
  • MySQL的数据类型
  • Service Worker
  • v-if和v-for连用出现的问题
  • 初识 beanstalkd
  • 基于遗传算法的优化问题求解
  • 记一次用 NodeJs 实现模拟登录的思路
  • 技术:超级实用的电脑小技巧
  • 力扣(LeetCode)56
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 学习HTTP相关知识笔记
  • 一起参Ember.js讨论、问答社区。
  • 与 ConTeXt MkIV 官方文档的接驳
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • 支付宝花15年解决的这个问题,顶得上做出十个支付宝 ...
  • ​补​充​经​纬​恒​润​一​面​
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • (C++17) std算法之执行策略 execution
  • (NO.00004)iOS实现打砖块游戏(九):游戏中小球与反弹棒的碰撞
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (第27天)Oracle 数据泵转换分区表
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (十一)c52学习之旅-动态数码管
  • (源码分析)springsecurity认证授权
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • *2 echo、printf、mkdir命令的应用
  • .net framework profiles /.net framework 配置
  • .net6使用Sejil可视化日志
  • .NET成年了,然后呢?
  • @hook扩展分析
  • [.net]官方水晶报表的使用以演示下载