剑指offer(二十三):二叉搜索树的后序遍历序列(Java版)

描述

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

示例1

输入:

[4,8,6,12,16,14,10]

返回值:true

首先我们要知道后序遍历为先遍历左节点,再遍历右节点,最后遍历根节点。从后序遍历的特性可以得出,最后一个树为根节点。数组中大于此值的即为右子树的值,而小于此值的则为左子树的值,依次递归,如果判断左子树的值有大于根节点或者右子树的值,则说明此数组不是某二叉搜索树的后序遍历的结果

第一种解法,递归解法,代码如下

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

    public boolean judgeTree(int[] arr,int start , int end){
        if(start >= end){
            return true;
        }
        //j代表 左子树 和 右子树的分界
        int j = start;
        for (; j < end; j++ ){
            if(arr[j] > arr[end]){
                break;
            }
        }
        for (int i =j; i < end; i++){
            if(arr[i] < arr[end]){
                return false;
            }
        }
        return judgeTree(arr,start, j -1) && judgeTree(arr, j,end-1);
    }

第二种,非递归,对于一个二叉搜索树来说,左子树的每个节点肯定要比右子树的每个节点要小,所以我们可以不断的去掉数组的最后一个值,并且把剩下的部分分成大于此值的一部分和小于此值的一部分,只要一直能满足此规则,说明就符合二叉搜索树的后序遍历,代码如下

public boolean secondVerifySquenceOfBST(int [] sequence) {
        if(null == sequence || sequence.length < 1){
            return false;
        }
        int length = sequence.length;
        if(length == 1){
            return true;
        }
        length = length -1;
        int i =0;
        while (length > 0){
            for (; i < length ; i++){
                if(sequence[i] > sequence[length]){
                    break;
                }
            }
            for (; i < length ; i++){
                if(sequence[i] < sequence[length]){
                    break;
                }
            }
            if(i < length){
                return false;
            }
            length --;
            i = 0;
        }

        return true;
    }

完整代码如下

public class MainVerifySquenceOfBST {

    public static void main(String[] args) {
        int[] arr = {7,4,6,5};
        MainVerifySquenceOfBST mainVerifySquenceOfBST = new MainVerifySquenceOfBST();
        boolean b = mainVerifySquenceOfBST.secondVerifySquenceOfBST(arr);
        System.out.println("b = " + b);

    }

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

    public boolean judgeTree(int[] arr,int start , int end){
        if(start >= end){
            return true;
        }
        //j代表 左子树 和 右子树的分界
        int j = start;
        for (; j < end; j++ ){
            if(arr[j] > arr[end]){
                break;
            }
        }
        for (int i =j; i < end; i++){
            if(arr[i] < arr[end]){
                return false;
            }
        }
        return judgeTree(arr,start, j -1) && judgeTree(arr, j,end-1);
    }

    public boolean secondVerifySquenceOfBST(int [] sequence) {
        if(null == sequence || sequence.length < 1){
            return false;
        }
        int length = sequence.length;
        if(length == 1){
            return true;
        }
        length = length -1;
        int i =0;
        while (length > 0){
            for (; i < length ; i++){
                if(sequence[i] > sequence[length]){
                    break;
                }
            }
            for (; i < length ; i++){
                if(sequence[i] < sequence[length]){
                    break;
                }
            }
            if(i < length){
                return false;
            }
            length --;
            i = 0;
        }

        return true;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值