Given an array of numbers, verify whether it is the correct preorder traversal sequence of a binary search tree.
You may assume each number in the sequence is unique.
Consider the following binary search tree:
5 / \ 2 6 / \ 1 3
Example 1:
Input: [5,2,6,1,3] Output: false
Example 2:
Input: [5,2,1,3,6] Output: true
Follow up:
Could you do it using only constant space complexity?
A:
每次找到小于的, 然后分开查询
class Solution { public: bool verifyPreorder(vector<int>& preorder) { return helper(preorder, 0, preorder.size()-1); } private: bool helper(vector<int>& preorder, int start, int end){ if(start >= end) // just one value return true; int val = preorder[start]; int mid = start+1; // mid point to first position either go-beyond, or with bigger value while(mid<=end && preorder[mid] < val){ mid++; } for(int i = mid; i<=end;i++){ if(preorder[i] < val ) return false; } return helper(preorder, start+1,mid-1) && helper(preorder, mid, end); } };
上面这个方法,说都通过了,可是有点儿慢。 修改下,加上范围. 这样,可以省掉上面的for循环
class Solution { public: bool verifyPreorder(vector<int>& preorder) { return helper(preorder, 0, preorder.size()-1, INT_MIN, INT_MAX); } private: bool helper(vector<int>& preorder, int start, int end, int lower, int upper){ if(start > end) // just one value return true; int val = preorder[start]; if(val <=lower || val >= upper) return false; if(start == end) return true; int mid = start+1; // mid point to first position either go-beyond, or with bigger value while(mid<=end && preorder[mid] < val){ if(preorder[mid]<=lower) return false; mid++; } return helper(preorder, start+1,mid-1, lower, val) && helper(preorder, mid, end, val, upper); } };
这次通过了, 可是,只是faster than 5.65%
观察得知,我们还是有了个while 循环,考虑去掉。 用stack 来表示。
This problem is very interesting. Recursive approach is very straightforward, though solution is likely of O(nlogn)/O(logn) time/space complexity (avg), or O(N^2)/O(N) worst case.
The key to optimize is to recall how iterative(non-recursive)
pre-order traversal works, then follow the same idea to "reconstruct" BST from preorder sequence, during which we need a stack to keep track of node path from root. The trick here is to use input preorder sequence to simulate the stack in-place. For verification purpose, we need to maintain a "lower bound" variable: when we visit a node that is the right child of its parent, the parent's value must be lower bound of all subsequent values.
class Solution { public: bool verifyPreorder(vector<int>& preorder) { stack<int> st; int lower_bound = INT_MIN; for(int i = 0;i< preorder.size();i++){ int v = preorder[i]; if(v <= lower_bound) // check that it's in the range return false; if(st.empty() || v < st.top()){ st.push(v); }else{ lower_bound = st.top(); st.pop(); i--; // this is the KEY, step back so we can check with grandparent } } return true; } };
Mistakes:
No comments:
Post a Comment