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'#'
representingnull
pointer.
Note: You may assume that the input format is always valid, for example if could never contain two consecutive commas such as "1,,3" For example: "9, 3, 4, #, #, 1, #, #, 2, #, 6, #, #", return true "1, #" return false "9, #, #, 1" return false*/
_9_
/ \
3 2
/ \ / \
4 1 # 6
/ \ / \ / \
# # # # # #
_9_
/ \
3 2
/ \ / \
# 1 # 6
/ \ / \
# # # # we substitute the "4, #, #" to "#"
By doing this recursively, the final result will be a only a "#" left.
#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;
bool isValidSerialization(string preorder) {
if(preorder.size() == 0) return true;
if(preorder.size() % 2 == 0) return false;
stack<char> nodes;
for(int i = 0; i < preorder.size(); ++i) {
if(preorder[i] == ',') continue;
if(nodes.size() >= 3) {
char tmp_1 = nodes.top();
if(tmp_1 == '#') {
nodes.pop();
char tmp_2 = nodes.top();
if(tmp_2 == '#') {
nodes.pop();
nodes.pop();
nodes.push('#');
} else {nodes.push(tmp_1);}
}
}
nodes.push(preorder[i]);
}
return !nodes.empty() && (nodes.top() == '#');
}
int main(void) {
string preorder_test = "9, 3, 4, #, #, 1, #, #, 2, #, 6, #, #";
cout << isValidSerialization(preorder_test) << endl;
string preorder_test1 = "1, #";
cout << isValidSerialization(preorder_test1) << endl;
string preorder_test2 = "9, #, #, 1";
cout << isValidSerialization(preorder_test2) << endl;
}