1066 · Verify Preorder Serialization of a Binary Tree
Algorithms
Medium
Description
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
Example 1:
Input: tree = “#”
Output: true
Explanation:
Empty tree is legal.
Example 2:
Input: tree = “9,3,4,#,#,1,#,#,2,#,6,#,#”
Output: true
Example 3:
Input: tree = “1,#”
Output: false
Explanation:
It's not a complete tree.
Example 4:
Input: tree = “9,#,#,1”
Output: false
Explanation:
It's not a tree.
解法1:
helper() 函数里面:
class Solution {
public:
/**
* @param preorder: a string
* @return: return a bool
*/
bool isValidSerialization(string &preorder) {
// write your code here
vector<string> tokens;
stringstream ss(preorder);
string token;
while (getline(ss, token, ',')) {
tokens.push_back(token);
}
int index = 0;
return helper(tokens, index) && index == tokens.size() - 1;
}
private:
bool helper(vector<string> &tokens, int& index) {
if (index >= tokens.size()) return false;
if (tokens[index][0] == '#') {
return true;
} else {
return helper(tokens, ++index) && helper(tokens, ++index);
}
}
};
解法2:用stringstream。很方便。
注意:因为preorder是用’,'而不是空格隔开的,所以得到下一个token是用getline(ss, token, ‘,’)。如果返回false, 说明ss已经读完。
如果preorder是用空格隔开,则可以简单的用ss >> token得到下个token,其返回值false也是说明ss已经读完。
class Solution {
public:
/**
* @param preorder: a string
* @return: return a bool
*/
bool isValidSerialization(string &preorder) {
// write your code here
vector<string> tokens;
stringstream ss(preorder);
string token;
return helper(ss) && !getline(ss, token, ',');
}
private:
bool helper(stringstream &ss) {
string token;
if (!getline(ss, token, ',')) return false;
if (token[0] == '#') {
return true;
} else {
return helper(ss) && helper(ss);
}
}
};
解法3:
参考的labuladong的解法。
class Solution {
public:
/**
* @param preorder: a string
* @return: return a bool
*/
bool isValidSerialization(string &preorder) {
if (!preorder.empty() && preorder.find(',') == string::npos) return preorder[0] == '#';
vector<string> tokens;
stringstream ss(preorder);
string token = "";
int edgeCount = 1; //注意,edgeCount要初始化为0。
while (getline(ss, token, ',')) {
if (token[0] == '#') {
edgeCount--; //空节点消耗一个edge,不生成任何edge。
if (edgeCount < 0) return false;
} else {
//edgeCount++;
edgeCount--; //非空节点消耗一个edge, 又生出两个edge。 注意case "#,2,#"
if (edgeCount < 0) return false;
edgeCount += 2;
}
}
return edgeCount == 0;
}
};