剑指 offer 面试题 33 二叉搜索树的遍历序列(递归、单调栈 O(n))

二叉搜索树的遍历序列

个人博客

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

题解
  • 递归分治

    • 算法思想
      • 递归的判断搜索树的左右子树是不是符合左子树都小于根节点,右子树都大于根节点
      • 如何设置递归终止条件
        • 当查找到左子树有元素大于根节点时或者右子树有元素小于根节点时返回 false
        • 当数组大小小于等于 2 的时候
    • 复杂度分析
      • 时间复杂度 O(N^2): 每次调用 recur(i,j)recur(i,j) 减去一个根节点,因此递归占用 O(N)O(N) ;最差情况下(即当树退化为链表),每轮递归都需遍历树所有节点,占用O(n)。
      • 空间复杂度O(n):最差情况下(树退化为链表),递归深度将达 n
    class Solution {
        public boolean verifyPostorder(int[] postorder) {
            return virifyBinarySearchRecurse(postorder,0,postorder.length-1);
        }
        boolean virifyBinarySearchRecurse(int[] nodes,int start,int end){
            if(end - start <= 1)return true;
            int rightstart = end -1;
            boolean finded = false;
            for(int i = start;i < end;i++){
                if(nodes[i] > nodes[end] && !finded){
                    rightstart = i - 1;
                    finded = true;
                }
                if(nodes[i] < nodes[end] && finded)return false;
            }
            return virifyBinarySearchRecurse(nodes,start,rightstart) && virifyBinarySearchRecurse(nodes,rightstart + 1,end-1);
        }
    }
    

    MRDsAF

  • 单调栈

    • 算法思想

      • 后续遍历的倒序为 [ 根节点 | 右子树 | 左子树 ] ,此时可以利用单调栈,当将要加入的节点的值大于栈顶时,直接加入,当要加入的元素小于栈顶的时候,将栈顶元素弹出,判断此时栈顶元素是否大于将要加入的元素,直到栈顶元素小于将要加入元素或者栈空。然后将要加入的元素加入
      • 在此过程中,如果将要加入的元素大于最后一次弹出的元素,则说明不是二叉搜索树
    • 复杂度分析

      • 时间复杂度 O(n):每个元素出栈入栈一次,
      • 空间复杂度 O(n):二叉树搜索树退化为单链表,栈的深度为 n
    class Solution {
        public boolean verifyPostorder(int[] postorder) {
            Deque<Integer> stack = new ArrayDeque<>();
            int prev = Integer.MAX_VALUE;
            for(int i = postorder.length -1;i >= 0;i--){
                if(postorder[i] > prev)return false;
                while(!stack.isEmpty() && postorder[i] < stack.peek()){
                    prev = stack.pop();
                }
                stack.push(postorder[i]);
            }
            return true;
        }
    }
    

    JOIIni

总结
  • 利用单调栈方法时间复杂度显然更好,但是思路确实挺难,我想了好久才明白,让我去证明正确性,估计是不可能的了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值