Verify Preorder Serialization of a Binary Tree

时间:2022-10-27 14:48:11

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

分析:https://www.hrwhisper.me/leetcode-verify-preorder-serialization-of-a-binary-tree/

这个方法简单的说就是不断的砍掉叶子节点。最后看看能不能全部砍掉。

以例子一为例,:”9,3,4,#,#,1,#,#,2,#,6,#,#” 遇到x # #的时候,就把它变为 #

我模拟一遍过程:

  1. 9,3,4,#,# => 9,3,# 继续读
  2. 9,3,#,1,#,# => 9,3,#,# => 9,# 继续读
  3. 9,#2,#,6,#,# => 9,#,2,#,# => 9,#,# => #
 public boolean isValidSerialization(String preorder) {
Stack<String> stack = new Stack<String>();
String[] arr = preorder.split(","); for (int i = ; i < arr.length; i++) {
stack.push(arr[i]);
while (stack.size() >= && stack.get(stack.size() - ).equals("#")
&& stack.get(stack.size() - ).equals("#") && !stack.get(stack.size() - ).equals("#")) {
stack.remove(stack.size() - );
stack.remove(stack.size() - );
}
} if (stack.size() == && stack.peek().equals("#"))
return true; return false;
}

另一种解法:https://www.hrwhisper.me/leetcode-verify-preorder-serialization-of-a-binary-tree/

看了 dietpepsi 的代码,确实思路比我上面的更胜一筹:

In a binary tree, if we consider null as leaves, then

  • all non-null node provides 2 outdegree and 1 indegree (2 children and 1 parent), except root
  • all null node provides 0 outdegree and 1 indegree (0 child and 1 parent).

Suppose we try to build this tree. During building, we record the difference between out degree and in degree diff = outdegree - indegree. When the next node comes, we then decrease diff by 1, because the node provides an in degree. If the node is not null, we increase diff by2, because it provides two out degrees. If a serialization is correct, diff should never be negative and diff will be zero when finished.

from :https://leetcode.com/discuss/83824/7-lines-easy-java-solution

我这里翻译一下:

对于二叉树,我们把空的地方也作为叶子节点(如题目中的#),那么有

  • 所有的非空节点提供2个出度和1个入度(根除外)
  • 所有的空节点但提供0个出度和1个入度

我们在遍历的时候,计算diff = outdegree – indegree. 当一个节点出现的时候,diff – 1,因为它提供一个入度;当节点不是#的时候,diff+2(提供两个出度) 如果序列式合法的,那么遍历过程中diff >=0 且最后结果为0.

 public boolean isValidSerialization(String preorder) {
String[] nodes = preorder.split(",");
int diff = ;
for (String node: nodes) {
if (--diff < ) return false;
if (!node.equals("#")) diff += ;
}
return diff == ;
}