Problem
One way to serialize a binary tree is to use preorder 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 '#'
.
|
|
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 preorder
, return true
if it is a correct preorder traversal serialization of a binary tree.
It is guaranteed that 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"
.
Note: You are not allowed to reconstruct the tree.
Examples
Example 1:
|
|
Example 2:
|
|
Example 3:
|
|
Solution
Method 1 - Using Stack
We can keep trimming the leaves until there are no more to remove. For example, if a sequence like 4 # #
is encountered, we simplify it to #
and continue. A stack is a suitable data structure for this purpose.
When iterating through the preorder traversal string, for each node:
- Case 1: You encounter a number
c
(non-null node):- A number represents the root of a new subtree. You consume one slot and push
2
slots onto the stack, as this node will have two children.
- A number represents the root of a new subtree. You consume one slot and push
- Case 2: You encounter a
#
(null node):- Subcase 2.1: The top of the stack represents a positive count (remaining slots):
- This null node consumes 1 slot, decrementing the top of the stack by 1.
- If the slot count at the top becomes 0, pop the stack as no further nodes can be added to this subtree.
- Subcase 2.2: The top of the stack already represents a completed subtree (slot
0
):- This signifies that the null node belongs to a previously completed right child.
- Continue popping the stack until it either becomes empty or the top of the stack indicates remaining slots for further children.
- Subcase 2.1: The top of the stack represents a positive count (remaining slots):
After processing all nodes
- If the stack is empty, the serialization is valid.
- If the stack is non-empty, the serialization is invalid, indicating there were unconsumed slots.
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
: Traversal of thepreorder
string (split by commas). - 🧺 Space complexity:
O(n)
: Maximum size of the stack is the number of nodes.
Dry Running the Code:
|
|
So, we processed the tree and replace it with #
.
Method 2 - Using a List Like a Stack
Code
|
|
Method 3 - Using in-degree and out-degree on tree nodes
In a binary tree, we can describe each node as contributing to the indegree and outdegree:
- Non-null nodes (
integer
):- Provide 2 outdegrees (for their left and right children).
- Contribute 1 indegree by occupying one position in the tree (as a child of their parent).
- Except the root, which has no parent and therefore does not contribute an indegree.
- Null nodes (
'#'
):- Provide 0 outdegrees (null nodes cannot have children).
- Contribute 1 indegree by occupying one position in the tree.
To validate whether the given preorder serialization is correct:
- Use a variable
diff
to track the difference between total outdegree and total indegree:- Start with
diff = 1
(the root provides an outdegree for the tree but does not consume an indegree).
- Start with
- Iterate through the nodes:
- Decrease
diff
by 1 for each node (all nodes consume one indegree). - If the node is non-null, increase
diff
by 2 to account for its outdegrees.
- Decrease
- If at any point
diff < 0
, the serialization is invalid (indegree exceeds outdegree, indicating an imbalance). - At the end, check if
diff == 0
. A valid serialization will have balanced indegree and outdegree.
Code
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
- The traversal of all nodes in the
preorder
string takes linear time. - Splitting the string using
split(",")
also takes linear time.
- The traversal of all nodes in the
- 🧺 Space complexity:
O(n)
- We require space for the
nodes
array after splitting the string.
- We require space for the