题目:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出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);
}
}