从右向左扫描,找到第一个比最右节点小的数,然后从那个数开始再向左搜索,查看有没有比最右节点大的数,有则非BST
如果没有,则对左子树区间和右子树区间进行递归
时间限制:1 秒
内存限制:32 兆
特殊判题:否
提交:724
解决:359
-
题目描述:
-
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
-
输入:
-
每个测试案例包括2行:
第一行为1个整数n(1<=n<=10000),表示数组的长度。
第二行包含n个整数,表示这个数组,数组中的数的范围是[0,100000000]。
-
输出:
-
对应每个测试案例,如果输入数组是某二叉搜索树的后序遍历的结果输出Yes,否则输出No。
-
样例输入:
-
75 7 6 9 11 10 847 4 6 5
-
样例输出:
-
YesNo
-
答疑:
- 解题遇到问题?分享解题心得?讨论本题请访问: http://t.jobdu.com/thread-8090-1-1.html
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class S24 {
public static void main(String[] args) throws FileNotFoundException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream("in.in"));
System.setIn(in);
Scanner cin = new Scanner(System.in);
while (cin.hasNextInt()) {
int n = cin.nextInt();
int[] buf = new int[n];
for(int i=0; i<n; i++){
buf[i] = cin.nextInt();
}
if(valid(buf)){
System.out.println("Yes");
}else{
System.out.println("No");
}
}
}
private static boolean valid(int[] buf) {
return rec(buf, 0, buf.length-1);
}
private static boolean rec(int[] buf, int left, int right){
if(left > right){
return true;
}
// 从右向左搜索,找到第一个小于right的值,p
int p = right-1;
while(p>=left && buf[p]>buf[right]){
p--;
}
for(int i=p; i>=left; i--){ // 从p继续向左扫描,如果有出现比right大的数则不是BST
if(buf[i] > buf[right]){
return false;
}
}
boolean b1 = rec(buf, left, p); // 递归检查左子树区间和右子树区间
boolean b2 = rec(buf, p+1, right-1);
return b1 && b2;
}
}