题目描述:
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:
Input: "9,3,4,#,#,1,#,#,2,#,6,#,#"
Output: true
Example 2:
Input: "1,#"
Output: false
Example 3:
Input: "9,#,#,1"
Output: false
判断一个序列是否可能为一个二叉树的前序遍历。其实我们通过分析可以发现规律,二叉树的每个节点有两个出度(左右节点为空也算在内),而除了根节点以外都有一个入度,那么对于n个节点,有2n个出度,其中有n-1个用于连接各个节点,其余的n+1个用于指向空的左右节点,所以在前序遍历序列中“#”的数量应该是节点数加一。仅仅满足数量关系还不够,假设已经遍历的序列中树节点的数量为k个,那么对应的2k个出度中,有k-1个用于连接各个节点,最少保留一个用于连接剩下的序列(最后一个节点除外),那么空节点的数量最多为k个。因此我们可以从序列首部开始遍历,在遍历到尾部之前,只要空节点数大于树节点数,直接返回false,在最后一个节点上,我们再判断它是否为空节点。
class Solution {
public:
bool isValidSerialization(string preorder) {
vector<string> v=split(preorder);
int count=0;
for(int i=0;i<v.size()-1;i++)
{
if(v[i]=="#") count--;
else count++;
if(count<0) return false;
}
if(v.back()=="#"&&count==0) return true;
else return false;
}
vector<string> split(string s)
{
int i=0;
int j=0;
vector<string> result;
while(j<s.size())
{
if(j==s.size()-1)
{
result.push_back(s.substr(i,j-i+1));
break;
}
else if(s[j]==',')
{
result.push_back(s.substr(i,j-i));
j++;
i=j;
}
else j++;
}
return result;
}
};