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

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

题目描述

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


image

示例:

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

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


提示:
数组长度 <= 1000

转载来源:力扣(LeetCode)


题目分析

  1. 二叉搜索树的特点:
    1.1. 左子树的所有节点永远小于等于父节点
    1.2. 右子树的所有节点永远大于等于右子树
    1.3. 左子树和右子树也是二叉搜索树
  2. 后续遍历的特点:左子树先遍历、右子树后遍历、父节点最后遍历

举例子: [1,3,2,6,5]

  • 根据特点2,根节点显然是5
  • 根据特点1.2,我们可以从根节点往前探索,比它大的都是右子树的,剩下的都是左子树的,所以右子树是[6],左子树是[1,3,2]
  • 然后对于特点1.1还没有得到验证,所有对于左子树[1,3,2],都必须确保每个元素都比5小,否则不符合二叉搜索树的特点,返回false
  • 如果特点1.1得到验证,那么只要证明特点1.3,整棵树就是满足二叉搜索树的特点了,1.3的证明很简单,对左子树和右子树也进行像整棵树一样的操作即可(递归)
    public boolean verifyPostorder(int[] postorder) {
        if(postorder.length == 1) return true;
        return verifyPostorder(postorder,0,postorder.length-1);
    }
    
    //验证当前数是否为二叉搜索树
    public boolean verifyPostorder(int[] postorder,int head,int tail) {
        if(head >= tail) return true;
        int parent = postorder[tail];  
        int rightHead = tail;
        //寻找右子树和左子树的分界点
        while(rightHead >= head){
            if(postorder[rightHead] >= parent)
                rightHead--;
            else
                break;
        }
        rightHead += 1;
        // 验证右子树是否为二叉搜索树
        if(!verifyPostorder(postorder,rightHead,tail-1))
            return false;
        // 验证左子树是否都比父节点小
        if(!verifyLeft(postorder,head,rightHead-1,parent))
            return false;
        // 验证左子树是否为二叉搜索树
        return verifyPostorder(postorder,head,rightHead-1);
    }

    public boolean verifyLeft(int[] postorder,int head,int tail,int parent){
        for(int i = head; i <= tail; i++){
            if(postorder[i] > parent)
                return false;
        }
        return true;
    }

你可能感兴趣的:(面试题33. 二叉搜索树的后序遍历序列)