题目:
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)如果是代表空节点的#,则看栈顶元素是否也是#,如果是,则说明我们遇到了一个叶子结点,此时模拟不断消除该叶子结点(弹出栈顶的两个元素,并将#压入栈),直到不存在当前需要消除的叶子结点。这是因为在前序遍历中,叶子结点在字符串中一定是以连续三个字符“value,#,#”的形式存在。
2)如果不满足上述消除叶子结点的条件,则将该字符入栈。
如果字符串是合法的二叉树前序遍历,则最终栈中会只有一个元素“#”,返回true。否则返回false。
代码:
class Solution {
public:
bool isValidSerialization(string preorder) {
int start = 0, end = 0;
stack<string> st;
while(start < preorder.size()) {
end = start;
while(end < preorder.size() && preorder[end] != ',') {
++end;
}
string word = preorder.substr(start, end - start);
if(word != "#") {
st.push(word);
}
else {
while(!st.empty() && st.top() == "#") {
st.pop();
if(st.empty()) {
return false;
}
st.pop();
}
st.push("#");
}
start = end + 1;
}
return st.size() == 1 && st.top() == "#";
}
};