Zenefits Interview - Can represent the pre-order list of a BST

Given a list of numbers, determine whether it can represent the pre-order traversal list of a binary search tree (BST).
 
Input
The first line contains the number of test cases, TT lines follow, consisting of two lines each.
The first line of each test case contains the number of nodes in the tree, N. In next line there will a list of N unique numbers, where each number is from the range [1, N].
 
Output
For each test case, print the string “YES” if there exists a BST whose pre-order traversal is equal to the list, otherwise print the string “NO” (without quotes, preserving capitalization).
 
Constraints
1 ≤ T ≤ 10
1 ≤ N ≤ 100
 
Sample Input
5
3
1 2 3
3
2 1 3
6
3 2 1 5 4 6
4
1 3 4 2
5
3 4 5 1 2
 
Sample Output
YES
YES
YES
NO
NO
 
Explanation
  • The first three cases are from the above examples.
  • In case 4, after encountering the 3, the 4tells us we are on the right sub-tree, which means no values smaller than 3 are allowed any longer. So when we see the 2 we know the list is invalid.
  • Similarly, in case 5, after encountering the 3, the 4 and 5 tell us we are on the right sub-tree, so the subsequent encounter of values 2 and 1, which belong in the left sub-tree, tells us that the list is not valid as a pre-order traversal of a BST.
public static boolean isValidPreorderBST(int[] A) {
	return isValidPreorderBST(A, 0, A.length-1);
}
public static boolean isValidPreorderBST(int[] A, int start, int end) {
	if(start >= end) return true;
	int i=start+1;
	for(; i<=end; i++) {
		if(A[i] > A[start]) break;
	}
	int j = i;
	while(j <= end) {
		if(A[j++] <= A[start]) return false;
	}
	return isValidPreorderBST(A, start+1, i-1) && isValidPreorderBST(A, i, end);
}

public static void main(String[] args) {
	String[] cases = new String[]{"1 2 3", "2 1 3", "3 2 1 5 4 6", "1 3 4 2", "3 4 5 1 2"};
	for(String s:cases) {
		String[] nums = s.split("\\s");
		int[] A = new int[nums.length];
		for(int i=0; i<A.length; i++) {
			A[i] = Integer.parseInt(nums[i]);
		}
		System.out.println(isValidPreorderBST(A));
	}
	
}

 

重构了一下,添加了min数组,保存从当前位置往后的最小值,省去了继续搜索比根节点值小的元素的时间。

public static boolean isValidPreorderBST(int[] A) {
	int n = A.length;
	if(n <= 1) return true;
	int[] min = new int[n];
	min[n-1] = A[n-1];
	for(int i=n-2; i>=0; i--) {
		min[i] = Math.min(min[i+1], A[i]);
	}
	return isValidPreorderBST(A, min, 0, n-1);
}
private static boolean isValidPreorderBST(int[] A, int[] min, int start, int end) {
	if(start >= end) return true;
	int i=start+1;
	for(; i<=end; i++) {
		if(A[i] > A[start]) break;
	}
	if(i<end && min[i+1] <= A[start]) return false;
	return isValidPreorderBST(A, min, start+1, i-1) && isValidPreorderBST(A, min, i, end);
}

 

以上解法的时间复杂度都是O(N^2)。

以下链接提供了O(N)的解法。

http://www.geeksforgeeks.org/construct-bst-from-given-preorder-traversa/

你可能感兴趣的:(interview)