要求在不重建樹的情況下,判斷一個(gè)字符串是否為某樹的先序遍歷序列。
使用遞歸求解。
若一個(gè)序列只有一個(gè)“#“,顯然這是正確的。
若一個(gè)序列的第一個(gè)元素不是"#",那么一個(gè)合法的序列一定可以分成三部分來看待:根(第一個(gè)元素),左子樹(從第二個(gè)元素開始算起到第x個(gè)元素),右子樹(從第x+1個(gè)元素算起到序列末尾)。因此,跳過第一個(gè)元素(根)后,我們在從第二個(gè)元素開始的子序列中,先嘗試找到一棵完整的樹(左子樹),如果找不到,那么顯然是不合法的。如果找到了,那么我們再從這棵完整的樹后面開始,嘗試找另一棵樹(右子樹),如果找不到,那么顯然是不合法的。
從第一個(gè)元素開始,如果找到了一個(gè)完整的樹,且長度和序列長度一致,那么就是合法的,否則就是非法的。
空間復(fù)雜度:O(1)(注意,為了簡便,我下面的代碼因?yàn)橛昧艘粋€(gè)數(shù)組放置從字符串中分離出來的序列,事實(shí)上是O(n),但其實(shí)這是可以省略的,并非算法本質(zhì))
時(shí)間復(fù)雜度:O(n)
代碼如下:
public class Solution {
public boolean isValidSerialization(String preorder) {
String[] x = preorder.split(",");
if (findTree(x, 0) == x.length) {
return true;
}
return false;
}
private int findTree(String[] preorder, int start) {
if (preorder.length - start == 0) {
return -1;
}
if (preorder[start].equals("#")) {
return start + 1;
}
int left = findTree(preorder, start + 1);
if (left < 0) {
return -1;
}
int right = findTree(preorder, left);
if (right < 0) {
return -1;
}
return right;
}
}