剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)

Posted CrazyPixel

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)相关的知识,希望对你有一定的参考价值。

leetcode《图解数据结构》剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)的解题思路和java代码,并附上java中常用数据结构的功能函数。

1. 题目

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

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

     5
    / \\
   2   6
  / \\
 1   3
示例 1:
输入: [1,6,3,2,5]
输出: false
示例 2:
输入: [1,3,2,6,5]
输出: true

提示:

数组长度 <= 1000

作者:Krahets
链接:https://leetcode.cn/leetbook/read/illustration-of-algorithm/5vwxx5/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2. 解题思路

使用递归分治的思路:

  • 根据最后一个值x,划分为左右子数组;
    • 查找比x大的元素,第一个比x大的元素下标为i,在此处划分数组[start,i-1][i,end]
  • 检查左右数组:左数组的元素均小于x,右数组的元素均大于x
    • 由于左数组元素和x的大小关系已经确定,只需要检查右数组和x的大小关系即可。
    • 如果右数组不符合要求,直接返回false;否则继续执行下一步
  • 对左右子数组,重复上述步骤;

终止条件:数组为空或者只有一个元素,返回true

3. 数据类型功能函数总结

//数组
int len=arrayname.length;//数组长度

4. java代码

class Solution 
    public boolean verifyPostorder(int[] postorder) 
        return recur(postorder,0,postorder.length-1);
    
    public boolean recur(int[] postorder,int start,int end)
        if(end-start<=1)
            return true;
        
        else
            int root_val=postorder[end];
            int i=start;
            for(i=start;i<end;i++)
                if(postorder[i]>root_val)
                    break;
                
            
            //得到i,左右数组[start,i-1],[i,end-1]
            //检查左右数组
            int flag=0;
            for(int j=i;j<end && flag==0;j++)
                if(postorder[j]<root_val)
                    flag=1;
                
            
            if(flag==0)
                return  recur(postorder,start,i-1)&&recur(postorder,i,end-1);
            
            else
                return false;
            

        
    

5. 踩坑小记

递归调用,显示StackOverflowError

递归函数的部分为:

if(flag==0)
    return  recur(postorder,start,i-1)&&recur(postorder,i,end-1);

而我一开始写成了:

if(flag==0)
    return  recur(postorder,start,i-1)&&recur(postorder,i,end);

然后一直报错显示StackOverflowError,后来发现是右数组划分的时候,传入end就会导致后序遍历一直停留在和根节点的比较上,无法退出循环,导致栈溢出。

剑指Offer对答如流系列 - 二叉搜索树的后序遍历序列

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

题目描述

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

例如,输入数组{5、7、6、9、11、10、8},则返回true,因为这个整数序列是下图二叉搜索树的后序遍历结果。
技术图片

如果输入的数组是{7、4、6、5},则由于没有哪棵二叉搜索树的后序遍历是这个序列,因此返回false。

问题分析

后序遍历 遍历顺序是 :左子树 —> 右子树 —> 根结点(最后遍历根节点)

根据二叉搜索树的特点,左子树节点的值< 根节点的值 < 右子树节点的值
技术图片

数组 {5、7、6、9、11、10、8}

结合上面数字可以说 二叉树后序遍历数组的最后一个数为根结点,剩余数字中,小于根结点的数字(即左子树部分)都排在前面,大于根结点的数字(即右子树部分)都排在后面。

问题解答

  public boolean verifySquenceOfBST(int[] sequence) {
        if(sequence== null || sequence.length<=0) {
            return false;
        }
        return verifyCore(sequence, 0, sequence.length-1);
    }

    private boolean verifyCore(int[] sequence,int start,int end) {
        if(start >= end) {
            return true;
        }
        
        //判断左子树
        int mid=start;
        while(sequence[mid]<sequence[end]) {
            mid++;
        }

        //判断右子树
        for(int i=mid;i<end;i++) {
            if(sequence[i]<sequence[end]) {
                return false;
            }
        }
        return verifyCore(sequence, start, mid-1)&&verifyCore(sequence, mid, end-1);
    }

以上是关于剑指 Offer 33. 二叉搜索树的后序遍历序列(java解题)的主要内容,如果未能解决你的问题,请参考以下文章

Java 剑指offer(33) 二叉搜索树的后序遍历序列

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

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

剑指 Offer 33. 二叉搜索树的后序遍历序列(递归,二叉搜索树,后序遍历,Java)

剑指 Offer 33. 二叉搜索树的后序遍历序列(递归,二叉搜索树,后序遍历,Java)

剑指 Offer 33. 二叉搜索树的后序遍历序列-递归分治