Serialize and Deserialize Binary Tree

hard

Serialization encodes a binary tree as a string; deserialization reconstructs the exact tree from that string. Implement a serialize and a deserialize so that deserialize(serialize(root)) returns a tree identical to the original.

Here you're given the root; return deserialize(serialize(root)) — the reconstructed tree, which the grader compares against the input. The tree is given/returned in level-order (breadth-first), using null for missing children.

Hints

Encode empty children with a sentinel (like '#') so the structure is preserved.
A single preorder walk with null markers uniquely encodes the tree.
Deserialize by reading the tokens back in the same order the serializer wrote them.

Common doubts

Without them a single traversal is ambiguous; recording nulls restores exactly which children are present.
No — preorder or level-order both work, as long as serialize and deserialize use the same one.
It doesn't need to: it recursively consumes a node's entire left subtree, then its right, so token consumption self-delimits.

Interview follow-ups

A BST needs only preorder (no null markers) — the ordering property lets deserialize infer structure via value bounds.
Record each node's child count (or a group terminator) so deserialize knows how many children to read.

Fun facts

  • The null-marker preorder string is a complete, order-preserving fingerprint of a tree — equal strings mean identical trees.
  • This encoding is the basis of the 'subtree of another tree' trick: substring match on serialized forms.

Asked at

AmazonFacebookGoogleMicrosoft
Frequently Sometimes Occasionally
Example 1
Input: root = [1, 2, 3, null, null, 4, 5]
Output: [1, 2, 3, null, null, 4, 5]
serialize then deserialize reproduces the same tree.
Example 2
Input: root = []
Output: []
An empty tree round-trips to empty.
Constraints

- The number of nodes is in the range [0, 10^4] - -1000 <= Node.val <= 1000

Solve this problem →