331. Verify Preorder Serialization of a Binary Tree

思路一

砍掉叶子节点
两个叶子节点访问后就将该父节点置为叶子节点,这样一个树访问完成后只剩下一个叶子节点
因此需要一个栈来存放先序遍历,对于连续栈中两个##,删除##,并且将栈顶替换为#

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
public boolean isValidSerialization(String preorder) {
if(preorder == null || preorder.length() == 0){
return false;
}
Stack<String> stack = new Stack<String>();
String[] s = preorder.split(",");
for (String string : s) {
//注意这里是while,因为遇到连续##就要替换
while(string.equals("#") && !stack.isEmpty() && stack.peek().equals("#")){
//将#pop
stack.pop();
if(stack.empty()){
return false;
}
//将栈顶元素替换为#
stack.pop();
}
stack.push(string);
}
if(stack.size() == 1 && stack.peek().equals("#")){
return true;
}
return false;
}

对于后序遍历,是遇到数字替换连续##

思路二

入度与出度的差
对于一个树来说分为叶子节点和非叶节点

  • 非叶子结点:出度2,入度1(不包括根结点)
  • 叶子结点:出度0,入度1

因此diff = 出度 - 入度 = 1,因为根结点入度为0
所以对于一个正确的树,一定会有diff = 1
且对于任何一个节点,diff都是非负数
对于每一个节点进入,diff–,而若是非叶子节点,diff+=2

1
2
3
4
5
6
7
8
9
10
11
12
public boolean isValidSerialization(String preorder) {
String[] nodes = preorder.split(",");
int diff = 1;
for (String node : nodes) {
if (--diff < 0)
return false;
if (!node.equals("#"))
diff += 2;
}
return diff == 0;
}