My code:
public class Solution {
public boolean verifyPreorder(int[] preorder) {
if (preorder == null || preorder.length == 0) {
return true;
}
return check(preorder, 0, preorder.length - 1);
}
private boolean check(int[] preorder, int begin, int end) {
if (begin >= end) {
return true;
}
int i = begin + 1;
while (i <= end) {
if (preorder[i] < preorder[begin]) {
i++;
}
else {
break;
}
}
int j = i - 1;
while (i <= end) {
if (preorder[i] < preorder[begin]) {
return false;
}
else {
i++;
}
}
return check(preorder, begin + 1, j) && check(preorder, j + 1, end);
}
}
我自己寫了出來,但發現很慢。
采用的是 dfs的思想,
發現preorder 一定可以分成三塊:
頭結點,之后一塊總比他小,緊接著一塊,總比他大。
所以我先檢查這個特征是否滿足。
如果滿足,再分別檢查第二塊和第三塊是否滿足要求,其實就是檢查左子樹右子樹,是否滿足要求。
然后看了答案,發現有更加快的做法。
My code:
public class Solution {
public boolean verifyPreorder(int[] preorder) {
if (preorder == null || preorder.length == 0) {
return true;
}
Stack<Integer> st = new Stack<Integer>();
int pre = Integer.MIN_VALUE;
for (int i = 0; i < preorder.length; i++) {
if (preorder[i] < pre) {
return false;
}
else {
while (!st.isEmpty() && preorder[i] > st.peek()) {
pre = st.pop();
}
st.push(preorder[i]);
}
}
return true;
}
}
reference:
https://discuss.leetcode.com/topic/21217/java-o-n-and-o-1-extra-space
time: O(n)
space: O(n)
這個利用的原理差不多。但是效率更高。
preorder總是先把左邊一條線訪問,所以他們的特點是從大變小。
如果突然碰到一個比棧頂更大的數,說明跳到了上一層結點的右孩子了。
那么就可以把比他小的結點都彈出去,然后更新low為自己的值。
如果碰到值比自己小的,說明來來錯地方了。
這道題目的意思是什么:
記住,遍歷的一定是 valid bst,我們要做的是,preorder this valid BST, -> array, 我們堅持這個array是否是我們預計的。
當然,還可以把棧去了,用原數組充當棧,但我感覺沒必要。
Anyway, Good luck, Richardo! -- 09/06/2016