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

236 阅读2分钟

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

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情

1、题目📑

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

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

     5
    / \
   2   6
  / \
 1   3

实例1

输入: [1,6,3,2,5]

输出: false

实例2

输入: [1,3,2,6,5]

输出: true

提示:

  • 数组长度 <= 1000

2、思路🧠

方法一:递归分治

后序遍历[ 左子树 | 右子树 | 根节点 ] ,即 左、右、根 。

二叉搜索树定义: 左子树中所有节点的值 < 根节点的值;右子树中所有节点的值 > 根节点的值;其左、右子树也分别为二叉搜索树。

递归过程

  1. 递归结束条件
    • 当遍历到叶子节点结束循环
  2. 递归回溯:
    • 在递归之前需要直到最后一个节点为整棵树的根节点
    • 找到左子树中所有的节点,找到第一个大于根节点的节点位置,此处我们用 left 标记,其 从 ileft - 1 的位置为左子树的所有元素
    • 因此,可以划分出左子树、右子树的区间,左子树【i,left - 1】,右子树【left , j - 1】,根节点为【j】
    • 依次递归左子树、右子树判断是否为二叉搜索树
  3. 返回值
    • 右子树的遍历已经到了根节点,判断整颗树是否是二叉搜索树
    • 递归左子树【i,left - 1】,判断左子树是否是二叉搜索树
    • 递归右子树【left , j - 1】,判断右子树是否是二叉搜索树

废话少说~~~~~上代码!

3、代码👨‍💻

第一次commit AC

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

        return right == j && recur(i, left - 1, postorder) && recur(left, right - 1, postorder);
    }
}

时间复杂度:O(N2) 每次调用 recur(i , j) 减去一个根节点,递归占用 O(N)

空间复杂度:O(N) 最坏情况深度为N

image-20220426175939086

4、总结

该题目的是对二叉搜索树的搜索和回溯的思想进行练习,本题的关键在于如何编写递归的条件,对于后序遍历要理解清楚基本概念,最容易想到的就是递归,自然就明白了递归和回溯。

❤️‍来自专栏《LeetCode基础算法题》欢迎订阅❤️‍

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

原题链接:剑指 Offer 33. 二叉搜索树的后序遍历序列 - 力扣(LeetCode) (leetcode-cn.com)