给定一个数组,如果给定的数组是二进制搜索树的先序遍历结果,则返回true,否则返回false。时间复杂度为O(n)。
例子:
输入: pre[] = {2, 4, 3}
输出: true
下面是上面数组对应的二叉搜索树
2
\
4
/
3
输入: pre[] = {2, 4, 1}
Output: false
上面的数组不对应任何二叉搜索树.
输入: pre[] = {40, 30, 35, 80, 100}
输出: true
对应的二叉搜索树如下:
40
/ \
30 80
\ \
35 100
输入: pre[] = {40, 30, 35, 20, 80, 100}
输出: false
解法1(简单时间复杂度为O(N^2))
从头节点开始找到第一个大于头节点的位置 j. 如果j的后面存在小于头节点的值则返回false,否则递归的判断j前面的序列和j后面的序列,如果start>=end-1 返回TRUE。
代码:
static boolean VerifySquenceOfBST(int array[],int start,int end)
{
int point=array[start],i=start+1;
int right=start+1;
if(start>=(end-1))
return true;
//如果start>=end-1 返回TRUE。
while(i<end)
{
if(array[i]>point)
{
right=i;
break;
}
i++;
//找到第一个大于point的节点。
}
i=right+1;
while(i<end)
{
if(array[i]<=point)
return false;
i++;
//如果右边有比 point大的节点则返回FALSE,否则递归的判断左右子树。
}
return VerifySquenceOfBST(array,start+1,right)&&VerifySquenceOfBST(array,right,end);
}
解法2(使用stack时间复杂对为O(N))
1)创建一个空堆栈。
2)将root初始化为INT_MIN。
3)a.如果当前节点小于栈顶节点则将当前节点入栈,
b.如果当前节点大于栈顶节点,循环比较栈顶节点和当前节点如果当前节点大于栈顶节点则将root赋值为栈顶节 点值。将栈顶节点出栈,
c.如果当前节点小于栈顶节点返回FALSE
代码
// Java编程判断数组是不是二叉搜索树的前序遍历
import java.util.Stack;
class BinarySearchTree {
boolean canRepresentBST(int pre[], int n) {
// 创建一个空栈
Stack<Integer> s = new Stack<Integer>();
//初始化当前的root值为最小值
int root = Integer.MIN_VALUE;
// 遍历给定的数组
for (int i = 0; i < n; i++) {
//如果发现一个位于右子树的节点并且节点值小于root的值
// 返回false
if (pre[i] < root) {
return false;
}
// 如果 pre[i] 是右子树上的节点,
//删除栈中所有小于pre[i]节点的值
// 把最后一个删除的节点赋值给
// root.
while (!s.empty() && s.peek() < pre[i]) {
root = s.peek();
s.pop();
}
// 如果stack为空或者当前节点小于root节点
// 将当前节点入栈
s.push(pre[i]);
}
return true;
}
public static void main(String args[]) {
BinarySearchTree bst = new BinarySearchTree();
int[] pre1 = new int[]{40, 30, 35, 80, 100};
int n = pre1.length;
if (bst.canRepresentBST(pre1, n) == true) {
System.out.println("true");
} else {
System.out.println("false");
}
int[] pre2 = new int[]{40, 30, 35, 20, 80, 100};
int n1 = pre2.length;
if (bst.canRepresentBST(pre2, n) == true) {
System.out.println("true");
} else {
System.out.println("false");
}
}
}