【牛客 - 剑指offer】JZ33 二叉搜索树的后序遍历序列 Java实现


剑指offer题解汇总 Java实现

https://blog.csdn.net/guliguliguliguli/article/details/126089434

本题链接

知识分类篇 - 树 - JZ33 二叉搜索树的后序遍历序列

题目

在这里插入图片描述
题目主要信息

  • 题目给出一个一维数组sequence

  • 需要判断该数组sequence中的元素是否符合一个二叉搜索树的后序遍历顺序

    • 如果该数组sequence可以是一种二叉搜索树的后序遍历顺序,则返回true

    • 如果该数组sequence非二叉搜索树的后序遍历顺序,则返回false

方案一 单调栈(还没理解)

栈是一种仅支持在表尾进行插入和删除操作的线性表,这一端被称为栈顶,另一端被称为栈底

  • 元素入栈指的是把新元素放到栈顶元素上面,使之成为新的栈顶元素

  • 元素出栈指的是从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,是其相邻的元素成为新的栈顶元素

官方给的这个方法还没理解…

在这里插入图片描述

方案二 二叉树递归

递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此递归过程,最重要的就是查看能不能将原本的问题分解为更小的子问题,这是使用递归的关键。

思路

递归函数的参数包含三个信息:

  • 遍历序列
  • 树的起点索引位置
  • 树的终点索引位置

对于后序遍历的二叉搜索树来讲,终点位置就是根,然后从后往前找到第一个小于终点位置的节点,就是在序列中划分左右子树的分割位置。

只要能一直划分下去,直到递归最后是单个节点,则说明应该返回true,否则返回false

具体做法

  1. 首先对于给定列表长度为0的特殊情况返回false

  2. 递归函数中返回条件为l>=r,则返回true

  3. 递归函数中确定根节点为sequence[r],然后从后往前遍历找到左右子树分割点,进行继续递归

下面代码在官方所给代码上做了一定的修改,两个for循环的起始条件

import java.util.*;

public class Solution {
    public boolean VerifySquenceOfBST(int[] sequence) {
        if (sequence.length == 0) {
            return false;
        }
        return order(sequence, 0, sequence.length - 1);
    }

    public boolean order(int[] sequence, int l, int r) {
        // 剩一个节点的时候 返回 true
        if (l >= r) {
            return true;
        }
        int j;
        //mid用来记录根节点
        int mid = sequence[r];

        // 找到左子树和右子树的分界点,j代表左子树的最后一个索引位置
        //通过下面循环,cur最后为根节点,左子树后序遍历的最后一个节点
        for (j = r - 1; j >= l; j--) {
            int cur = sequence[j];
            if (cur < mid) {
                break;
            }
        }

        // 判断所谓的左子树中是否又不合法(不符合二叉搜索树)的元素
        for (int i = j - 1; i >= l; i--) {
            int cur = sequence[i];
            if (cur > mid) {
                return false;
            }
        }
        return order(sequence, l, j) && order(sequence, j + 1, r - 1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值