《剑指offer》二叉搜索树的后序遍历序列

题目:

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

思路:

二叉搜索树/二叉查找树的特点:
(1)若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值。
(2)任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。
(3)任意结点的左、右子树也分别为二叉查找树。
(4)没有键值相等的结点
后序遍历的顺序是 先遍历左子树再遍历右子树最后遍历根节点。
考虑递归思想。
那么正确的二叉搜索树的数组,最后一位肯定是根节点,往左走,刚好是 左子树的序列 和 右子树的序列,通过 左子树所有值要比根节点小,右子树的所有节点比根节点大 来判断两子树的边界,子树内容可以为空。
接下来继续判断 左右子树是否为二叉搜索树。
递归结束的条件:
如果 右子树全部满足要求,左子树为空 返回true,
如果 右子树满足要求后,左子树出存在且不满足要求,返回false,
剩下就是判断两颗子树是否满足要求,只有两颗子树都满足要求才返回true。
子树的边界一定要写对。一旦子树为空就结束递归,不要再进入递归内部,否则会返回false。
另外要注意这个函数:
Arrays.copyOfRange(T[ ] original,int from,int to)
将一个原始的数组original,从小标from开始复制,复制到小标to,生成一个新的数组。
注意这里包括下标from,不包括下标to
边界要写对,否则会出现数组为空的情况。
这里写图片描述

import java.util.Arrays;
public class Solution {
     public static boolean VerifySquenceOfBST(int [] sequence) {
            if(sequence==null||sequence.length==0)
                return false;
            int left=0,right=0,i=sequence.length-1;
            boolean flag1=true;
            boolean flag2=true;
            right=i-1;
            while(right>=0&&sequence[right]>sequence[i])
                right--;
            if(right==0)
                return true;
            left=right;
            while(left>=0&&sequence[left]<sequence[i])
                left--; 
            if(left!=-1)
                return false;
            if(sequence.length!=0)
            {
                if(right+1<i)
                {
                    int[] rightarr = Arrays.copyOfRange(sequence, right+1, i);
                    flag1=VerifySquenceOfBST(rightarr);
                }
                if(right+1>0)
                {
                    int[] leftarr= Arrays.copyOfRange(sequence, 0, right+1);
                    flag2=VerifySquenceOfBST(leftarr);
                }
                return flag1&&flag2;
            }     
            return true;
        }
public static void main(String[] args) {     
    int[] number={1,2,3,4,5};
    VerifySquenceOfBST(number);
    }
}

以下为精简版,思路一致

链接:https://www.nowcoder.com/questionTerminal/a861533d45854474ac791d90e447bafd
来源:牛客网

已知条件:后序序列最后一个值为root;二叉搜索树左子树值都比root小,右子树值都比root大。
1、确定root;
2、遍历序列(除去root结点),找到第一个大于root的位置,则该位置左边为左子树,右边为右子树;
3、遍历右子树,若发现有小于root的值,则直接返回false;
4、分别判断左子树和右子树是否仍是二叉搜索树(即递归步骤1、2、3)。

链接:https://www.nowcoder.com/questionTerminal/a861533d45854474ac791d90e447bafd
来源:牛客网

思路:找住二叉查找树的特点:左子树<根<=右子树  使用分治思想
public class Solution {
    public boolean VerifySquenceOfBST(int [] sequence) {
        if(sequence.length == 0){
            return false;
        }
        if(sequence.length == 1){
            return true;
        }
        return judge(sequence,0,sequence.length-1);
    }

    public boolean judge(int[] a,int start,int end){
        if(start >= end){
            return true;
        }
        int i = start;
        while(a[i] < a[end]){
            ++i;
        }
        for(int j=i;j<end;j++){
            if(a[j] < a[end]){
                return false;
            }
        }
        return judge(a,start,i-1) && judge(a,i,end-1);
    }
}

猜你喜欢

转载自blog.csdn.net/gsch_12/article/details/81361481