题目:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果。如果是则返回true,否则返回false。假设输入的数组的任意两个数字都互不相同。例如,输入数组{5,7,6,9,11,10,8},则返回true,因为这个整数序列是二叉搜索树的后序遍历结果。如果输入的数组是{7,4,6,5},则由于没有哪棵二叉搜索树的后序遍历结果是这个序列,因此返回false。
分析:
在后序遍历得到的序列中,最后一个数字是树的根节点的值。数组中前面的数字可以分为两部分;第一部分是左子树结点的值,它们都比根节点的值小;第二部分是右子树结点的值,它们都比根节点的值大。
以数组{5,7,6,9,11,10,8}为例,后序遍历结果的最后一个数字8就是根节点的值。在这个数组中,前3个数字5、7、6都比8小,是值为8的结点的左子树结点;后3个数字9、11、10都比8大,是值为8的结点的右子树结点。接下来用同样的方法确定与数组每一部分对应的子树的结构,这其实就是一个递归的过程。
再来分析另一个整数数组{7,4,6,5}。后序遍历的最后一个数字是根节点,由于第一个数字7大于5,因此对应的二叉搜索树中,根节点上没有左子树,数字7、4、6都是右子树结点的值。但我们发现右子树中有一个结点的值为4,比根节点的值5小,这违背了二叉搜索树的定义。因此,不存在一棵二叉搜索树,后序遍历序列是{7,4,6,5}。
解法:
package com.wsy;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] array = new int[]{5, 7, 6, 9, 11, 10, 8};
System.out.println(check(array, array.length));
}
public static boolean check(int[] array, int length) {
if (array == null || length < 0) {
return false;
}
int root = array[length - 1];
int i, j;
for (i = 0; i < length - 1; i++) {
if (array[i] > root) {
break;
}
}
for (j = i; j < length - 1; j++) {
if (array[j] < root) {
return false;
}
}
boolean left = true;
if (i > 0) {
left = check(Arrays.copyOfRange(array, 0, i), i);
}
boolean right = true;
if (i < length - 1) {
right = check(Arrays.copyOfRange(array, i, length - 1), length - i - 1);
}
return left && right;
}
}