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
算法思想一:(二叉树中所有节点的出度=入度)
根结点有2出度0入度,分支结点有2出度1入度,空结点有0出度1入度。遍历序列,判断出度是否等于入度!
记 K=出度-入度。如果序列化是正确的,那么 K 在任何时刻都不会小于0,并且最终结果等于0!
<span style="font-size:18px;">class Solution {
public:
string toA(string a){//将a=“3,#,#,2,#,#”变成A=“1##1##”
const int n=a.size();
string A;
int i=0;
while(i<n){
if(a[i]==',')
++i;
else if(a[i]=='#'){
A+="#";
++i;
}
else{
A+="1";
while(i<n&&a[i]!=','&&a[i]!='#')
++i;
}
}
return A;
}
</span>
<span style="font-size:18px;">
bool isValid(string s){//形参的格式为A="11##1##";
int k=1;
for(int i=0;i<s.size();++i){
k--;
if(k<0)return false;
if(s[i]=='1')
k+=2;
}
return k==0;
}</span>
<span style="font-size:18px;">bool isValidSerialization(string a) {
string s=toA(a);
return isValid(s);
}
};</span>
算法思想二:
遍历字符串,如果碰到连续的“数字,#,#”,就将其替换为一个“#”入栈,最后字符串若仅剩一个‘#’就是true。程序中:
首先将a=“3,#,#,2,#,#”变成A=“1##1##” 形式。利用栈(Stack)数据结构实现上述算法。
<span style="font-size:18px;"><span style="font-size:18px;">class Solution {
public:
string toA(string a){//将a=“3,#,#,2,#,#”变成A=“1##1##”
const int n=a.size();
string A;
int i=0;
while(i<n){
if(a[i]==',')
++i;
else if(a[i]=='#'){
A+="#";
++i;
}
else{
A+="1";
while(i<n&&a[i]!=','&&a[i]!='#')
++i;
}
}
return A;
}
bool isValid(string A){//形参的格式为A="11##1##";
const int n=A.size();
if(A[0]=='#'&&n==1)return true;
if(n<3)return false;
if(A[0]=='#')return false;
stack<char> s;
s.push(A[0]);
int i=1;
while(!s.empty()&&i<n){
if(A[i]=='1'){
s.push(A[i]);
++i;
}
else if(A[i]=='#'){
if(s.size()>1&&s.top()=='#'){
s.pop();
if(s.top()=='1'){
s.pop();
if(s.empty()){
s.push(A[i]);++i;
}
}else{
s.push('#');
s.push(A[i]);
++i;
}
}
else {
s.push(A[i]);
++i;
}
}
}
if(s.size()==1&&s.top()=='#')return true;
return false;
}
bool isValidSerialization(string preorder) {
string s=toA(preorder);
return isValid(s);
}
};</span></span>