Leetcode每日一题 331.验证二叉树的前序序列化

331. 验证二叉树的前序序列化

序列化二叉树的一种方法是使用前序遍历。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录,例如 #
     _9_
    /   \
   3     2
  / \   / \
 4   1  #  6
/ \ / \   / \
# # # #   # #

例如,上面的二叉树可以被序列化为字符串 "9,3,4,#,#,1,#,#,2,#,6,#,#",其中 # 代表一个空节点。

给定一串以逗号分隔的序列,验证它是否是正确的二叉树的前序序列化。编写一个在不重构树的条件下的可行算法。

每个以逗号分隔的字符或为一个整数或为一个表示 null 指针的 '#' 。

你可以认为输入格式总是有效的,例如它永远不会包含两个连续的逗号,比如 "1,,3" 。

示例 1:
输入: "9,3,4,#,#,1,#,#,2,#,6,#,#"
输出: true
示例 2:

输入: 1,#
输出:
false

示例 2:

输入: 1,#
输出:
false


一开始看到这题第一时间想到的是判断节点的入度出度,不过思路对了,但就是在奇妙的地方卡住了,永远剩下几个案例过不去,就很懵,然后看了下大佬的思路,学到了新姿势,用消除法去判断,就是当遇到“4,#,#”这种的,就将它转化为“#”,最后栈中只剩下一个“#”,那么这个树就是合理的,因为所有叶子节点都会有两个空节点,如果这是一颗合理的二叉树,那么我们将叶子节点变为空节点,之前的父节点最终也会变成叶子节点,直到最后,顶点也会变为一个空节点,思路新奇,然后就自己动手实现了一下。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class Solution {
public:
bool isValidSerialization(string preorder) {
int p_size = preorder.length();
if (p_size == 0)return false;
//关键点,是否遇到'#'
//遇到连续两个'#',代表这颗子树的末端
vector<string> v;
for (int i = 0; i < p_size;)
{
if (preorder[i] == ',')
{
i++;
continue;
}
if (preorder[i] != '#')
{
string tmp;
while(i<p_size && preorder[i]!=','){
tmp+=preorder[i++];
}
v.push_back(tmp);
}
else
{
v.push_back("#");
i++;
}

while(v.size()>2 && v.back() == "#" && *(v.rbegin()+1) == "#" && *(v.rbegin()+2) != "#")
{
v.pop_back();
v.pop_back();
v.pop_back();
v.push_back("#");
}
}

if(v.size() == 1 && v[0] == "#")return true;
return false;
}
};