↓Skip to main content
  1. LeetCode/

LeetCode 297: Serialize and Deserialize Binary Tree

·2 mins· ·
LeetCode Hard String Tree Depth-First-Search Breadth-First-Search Design Binary-Tree
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: hard First Attempt: 2026-10-25

  • Submissions: Accepted ×2

Approach
#

Pre-order alone does not determine the tree’s shape, but it does once null children are written out. Serialize with a pre-order DFS, write # for null, and separate values with commas (values may be negative or have several digits).

Deserialize by reading in the same pre-order:

  • On #, return None.
  • Otherwise create the node, then recursively build the left subtree, then the right.

Every subtree ends with # markers, so the recursion knows where the left subtree stops without any extra length information.

My Attempts
#

Accepted on the first try on 2026-10-25. I practiced it again on 10-27, switching the null marker from N to # and the iterator to a deque, and it passed on the first try again.

Solution
#

class Codec:
    def serialize(self, root):
        res = []

        def dfs(node):
            if not node:
                res.append("#")
                return
            res.append(str(node.val))
            dfs(node.left)
            dfs(node.right)

        dfs(root)
        return ",".join(res)

    def deserialize(self, data):
        vals = iter(data.split(","))

        def dfs():
            val = next(vals)
            if val == "#":
                return None
            node = TreeNode(int(val))
            node.left = dfs()
            node.right = dfs()
            return node

        return dfs()

Complexity
#

Both directions take O(n) time and O(n) space.

Mistakes to Avoid
#

  • Without null markers, a pre-order (or in-order) sequence matches many trees.
  • Without a separator, negative and multi-digit values run together.
  • list.pop(0) is O(n) and makes the whole thing O(n^2); use an iterator or a deque.
  • A very skewed tree makes the recursion deep; a BFS level-order format avoids that.

Interview Explanation
#

I serialize with a pre-order DFS, writing # for null and separating values with commas. To deserialize I read in the same pre-order: # returns null, otherwise I create the node and recursively build its left and then right subtree. Because nulls are marked, the recursion knows where each subtree ends. Both directions are O(n).

Related

LeetCode 449: Serialize and Deserialize BST
·2 mins
LeetCode Medium String Tree Depth-First-Search Breadth-First-Search Design Binary-Search-Tree Binary-Tree
LeetCode 449 note: for a BST, pre-order without null markers is enough; deserialize recursively with bounds in O(n)
LeetCode 124: Binary Tree Maximum Path Sum
·2 mins
LeetCode Hard Dynamic-Programming Tree Depth-First-Search Binary-Tree Dp-on-Trees
LeetCode 124 note: DFS returns the best downward chain and updates the answer with left chain + node + right chain at every node; drop negative chains
LeetCode 515: Find Largest Value in Each Tree Row
·1 min
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 515 note: BFS level order, taking the maximum of each level; start from -inf
LeetCode 314: Binary Tree Vertical Order Traversal
·2 mins
LeetCode Medium Hash-Table Tree Depth-First-Search Breadth-First-Search Sorting Binary-Tree
LeetCode 314 note: BFS with a column index; BFS is what guarantees top-to-bottom within a column and left-to-right within a row
LeetCode 117: Populating Next Right Pointers in Each Node II
·2 mins
LeetCode Medium Linked-List Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 117 note: connect next pointers level by level with BFS; for a non-perfect tree, looking only at the neighbour’s children breaks the chain
LeetCode 1448: Count Good Nodes in Binary Tree
·1 min
LeetCode Medium Tree Depth-First-Search Breadth-First-Search Binary-Tree
LeetCode 1448 note: pass the path maximum down during DFS; a node is good when its value is at least that maximum