Serialize and Deserialize Binary Tree — Coding Interview Walkthrough
You’re in a coding interview. The interviewer says: “Design an algorithm to serialize a binary tree to a string and deserialize it back to the tree.” The challenge isn’t the traversal itself; it’s choosing an encoding scheme that unambiguously represents null nodes so reconstruction is deterministic. Serialize and Deserialize Binary Tree is LeetCode #297, a Hard problem where clarity of design matters more than algorithmic complexity.
This walkthrough covers both BFS and DFS approaches, explains why encoding nulls is the key insight, and shows the DFS preorder solution that produces the cleanest code.
The Problem
Design a Codec class with:
serialize(root) -> str: encodes a tree to a string.deserialize(data: str) -> TreeNode: decodes a string back to the original tree.
The encoding format is your choice. There’s no right answer as long as serialization and deserialization are inverses of each other. (LeetCode #297)
Example
Input
root = [1,2,3,null,null,4,5]
Serialized
"1,2,null,null,3,4,null,null,5,null,null" (DFS preorder with null markers)
Deserialized Original tree reconstructed correctly.
Already comfortable with the solution? Practice it in a mock interview →
What Interviewers Are Actually Testing
This is a design problem. Interviewers want to see you make a clear design decision (BFS vs. DFS, delimiter choice, null representation), justify it, and implement both halves correctly.
| Skill | What Interviewers Observe |
|---|---|
| Null node encoding | Do you explicitly encode nulls so the tree can be reconstructed? |
| BFS or DFS choice | Can you implement either and explain the trade-offs? |
| Delimiter + format clarity | Do you use a consistent delimiter and parse it correctly? |
| Deserialize pointer management | Do you advance through the token list correctly? |
| Correctness on edge cases | Empty tree, single node, skewed tree? |
Step 1: Clarifying Questions
-
Can node values be negative? Yes. This means the delimiter can’t be
-. Use,as the separator between tokens. -
Is the tree a BST? No. It’s a general binary tree. Without BST ordering, you need null markers to determine structure.
-
What should
serialize(None)return? A string (e.g.,"null").deserialize("null")should returnNone. -
Is there a size constraint? Up to 10^4 nodes. Both O(n) approaches work fine.
Step 2: The Key Insight
Encode null nodes explicitly. Without representing nulls, you can’t distinguish a node with one child from a node with two children. With nulls encoded, the tree structure is fully determined by a single traversal.
A binary tree serialized as just its values (e.g., "1,2,3") is ambiguous: is 3 the right child of 1, or the right child of 2? With null markers ("1,2,null,null,3,null,null"), the structure is unambiguous.
Step 3: Approaches
DFS (preorder): Serialize root, then left, then right, using a sentinel for nulls. Reconstruct with a recursive function consuming one token at a time. Clean, compact, no queue.
BFS (level-order): Serialize level by level, the same format LeetCode uses. Reconstruct with a queue. Slightly more intuitive but more code.
Both are O(n) time and O(n) space. DFS is usually the better interview choice because the code is shorter.
Python Implementation: DFS (Recommended)
class Codec:
def serialize(self, root) -> str:
tokens = []
def dfs(node):
if not node:
tokens.append("null")
return
tokens.append(str(node.val))
dfs(node.left)
dfs(node.right)
dfs(root)
return ",".join(tokens)
def deserialize(self, data: str):
tokens = iter(data.split(","))
def dfs():
val = next(tokens)
if val == "null":
return None
node = TreeNode(int(val))
node.left = dfs()
node.right = dfs()
return node
return dfs()
Why this is interview-friendly:
iter()makes token consumption clean.next(tokens)advances the pointer automatically. No index tracking needed.- Symmetry between serialize and deserialize. Both follow the same preorder pattern: root, left, right.
- Null sentinels eliminate ambiguity. Every leaf has exactly two
"null"children in the serialized string.
Python Implementation: BFS (Alternative)
from collections import deque
class Codec:
def serialize(self, root) -> str:
if not root:
return "null"
result = []
queue = deque([root])
while queue:
node = queue.popleft()
if node:
result.append(str(node.val))
queue.append(node.left)
queue.append(node.right)
else:
result.append("null")
return ",".join(result)
def deserialize(self, data: str):
if data == "null":
return None
tokens = data.split(",")
root = TreeNode(int(tokens[0]))
queue = deque([root])
i = 1
while queue:
node = queue.popleft()
if tokens[i] != "null":
node.left = TreeNode(int(tokens[i]))
queue.append(node.left)
i += 1
if tokens[i] != "null":
node.right = TreeNode(int(tokens[i]))
queue.append(node.right)
i += 1
return root
Time & Space Complexity
| Time | Space | |
|---|---|---|
| serialize | O(n) | O(n) |
| deserialize | O(n) | O(n) |
Every node is visited once. The serialized string and recursion stack (or queue) are both O(n).
Common Interview Mistakes
-
Not encoding nulls. Without null markers, the tree can’t be uniquely reconstructed. This is the single most important design decision.
-
Choosing a delimiter that appears in values. Node values can be negative, so
-is a bad delimiter. Use,consistently. -
BFS deserialize index tracking. Off-by-one in the token index is a common bug. Each dequeued node consumes exactly two tokens (left child, right child). Tracking
icarefully is essential. -
Not handling the empty tree.
serialize(None)should return"null", anddeserialize("null")should returnNone. Missing this edge case is a silent bug. -
Using
split()without considering empty tokens."1,,2".split(",")produces["1", "", "2"]. Ensure your serialization never produces consecutive delimiters.
What a Strong Candidate Sounds Like
“I’ll use DFS preorder serialization with null markers. The preorder structure, root then left subtree then right subtree, combined with explicit nulls, uniquely encodes any binary tree. Deserialization mirrors the same traversal: consume one token, create a node or return null, then recurse left and right. An iterator over the token list keeps the implementation clean. O(n) time, O(n) space.”
Example Interview Dialogue
Interviewer: Why DFS over BFS?
Candidate: Both work, but DFS preorder produces cleaner code. The serialize and deserialize functions are symmetric: both follow root, left, right order. With BFS, the deserialize needs a queue and explicit index tracking, which is more code and more room for off-by-one errors.
Interviewer: Can you reconstruct a tree from just preorder without null markers?
Candidate: Not for a general binary tree. Without nulls, you can’t tell where the left subtree ends and the right subtree begins. For a BST, you could use the ordering property to determine the split, but for a general tree, null markers are required.
Related Problems
- Construct Binary Tree from Preorder and Inorder (LeetCode #105). Tree reconstruction using two traversals instead of null markers.
- Binary Tree Level Order Traversal (LeetCode #102). BFS level-order traversal mechanics, the foundation of the BFS approach.
- Flatten Binary Tree to Linked List (LeetCode #114). Tree serialization into a linear structure.
Practice This in a Mock Interview
Serialize and Deserialize Binary Tree rewards candidates who pick a clean encoding scheme upfront and explain it clearly before coding. The DFS preorder + null sentinel approach produces the most concise and elegant implementation. Practice choosing and justifying your approach before writing the first line.
Start a mock interview for Serialize and Deserialize Binary Tree on Intervu.
Further reading:
- How to Prepare for a Coding Interview in 2026, the complete roadmap and study plans
- Why LeetCode alone isn’t enough, and what to practice instead
- Practice any LeetCode problem as a live mock interview
- The Grind 75 Pathway, a structured study plan with AI practice links
- Browse all walkthroughs on GitHub, condensed solutions with code