One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #
.
_9_
/ \
3 2
/ \ / \
4 1 # 6
/ \ / \ / \
# # # # # #
For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#"
, where #
represents a null node.
Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree.
Each comma separated value in the string must be either an integer or a character '#'
representing null
pointer.
You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3"
.
Example 1:"9,3,4,#,#,1,#,#,2,#,6,#,#"
Return true
Example 2:"1,#"
Return false
Example 3:"9,#,#,1"
Return false
1. 栈
class Solution {
public:
bool isValidSerialization(string preorder) {
stack<char> stk;
bool isNum = false;
preorder.push_back(','); // dummy tail for(auto c: preorder){
if(c == '#'){
// absorb: search for pattern `#, number` backward
while(!stk.empty() && stk.top() == '#'){
stk.pop(); // pop `#`
if(stk.empty() || stk.top() == '#') return false; // pattern `#,#,#`
stk.pop(); // pop `number`
}
stk.push('#'); // replace `number` with `#` since it has been fully explored/validated
}else if(c == ','){
if(isNum) stk.push('n'); // indicate this is a number instead of using the real number
isNum = false;
}else{
isNum = true;
}
} return stk.size() == && stk.top() == '#';
}
};
2. 不用栈
class Solution {
public:
bool isValidSerialization(string preorder) {
string& s = preorder;
while (s.size() >= ) {
bool find_pattern = false;
for (int i = s.size()-; i>= ; i--) {
if (s[i] == '#' && s[i-] == '#' && s[i-] != '#') {
find_pattern = true;
int j = i--;
/* find the start place of pattern */
while (j > && s[j] != ',') j--;
s.replace(j+, i-j, "#"); /* replace s[j+1, i] to "#" */
break; /* start a trun search from the end */
}
}
if (!find_pattern) break;
} /* boundary: empty tree */
return (s.size() == && s[] == '#');
}
};
从右向左,若出现(数字,#,#)模式,则替换成一个#。最后若只剩一个#则合法,否则不合法。