剑指 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、思路🧠
方法一:递归分治
后序遍历: [ 左子树 | 右子树 | 根节点 ]
,即 左、右、根 。
二叉搜索树定义: 左子树中所有节点的值 < 根节点的值;右子树中所有节点的值 > 根节点的值;其左、右子树也分别为二叉搜索树。
递归过程:
- 递归结束条件
- 当遍历到叶子节点结束循环
- 递归回溯:
- 在递归之前需要直到最后一个节点为整棵树的根节点
- 找到左子树中所有的节点,找到第一个大于根节点的节点位置,此处我们用
left
标记,其 从i
到left - 1
的位置为左子树的所有元素 - 因此,可以划分出左子树、右子树的区间,左子树【i,left - 1】,右子树【left , j - 1】,根节点为【j】
- 依次递归左子树、右子树判断是否为二叉搜索树
- 返回值
- 右子树的遍历已经到了根节点,判断整颗树是否是二叉搜索树
- 递归左子树【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
4、总结
该题目的是对二叉搜索树的搜索和回溯的思想进行练习,本题的关键在于如何编写递归的条件,对于后序遍历要理解清楚基本概念,最容易想到的就是递归,自然就明白了递归和回溯。
❤️来自专栏《LeetCode基础算法题》欢迎订阅❤️
厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。
对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!
原题链接:剑指 Offer 33. 二叉搜索树的后序遍历序列 - 力扣(LeetCode) (leetcode-cn.com)