↓Skip to main content
  1. LeetCode/

LeetCode 449: Serialize and Deserialize BST

·2 mins· ·
LeetCode Medium String Tree Depth-First-Search Breadth-First-Search Design Binary-Search-Tree 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: medium First Attempt: 2026-10-25

  • Submissions: Accepted ×3

Approach
#

The difference from LC 297 is that this is a BST, so null markers are unnecessary and the string can be shorter.

  • Serialize: pre-order, values only.
  • Deserialize: the first pre-order value is the root. Recurse with a valid range (low, high) (Tree Template 3): if the next value is outside the range, it does not belong to this subtree, so return None and let an ancestor take it. The left subtree’s range is (low, val) and the right subtree’s is (val, high).

Each value is read once, so it is O(n). It is the same technique as LC 1008 (BST from pre-order).

My Attempts
#

All three submissions passed on the first try: on 10-25 with space separators and then commas, and a rewrite on 10-27.

The first version named its function inorder, but it appends before recursing, so it is actually pre-order. A real in-order sequence of a BST is just the sorted values, identical for every shape, and cannot be decoded.

Solution
#

class Codec:
    def serialize(self, root: Optional[TreeNode]) -> str:
        res = []

        def preorder(node):
            if not node:
                return
            res.append(str(node.val))
            preorder(node.left)
            preorder(node.right)

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

    def deserialize(self, data: str) -> Optional[TreeNode]:
        if not data:
            return None
        vals = deque(int(x) for x in data.split(","))

        def build(low, high):
            if not vals or not low < vals[0] < high:
                return None
            val = vals.popleft()
            node = TreeNode(val)
            node.left = build(low, val)
            node.right = build(val, high)
            return node

        return build(-inf, inf)

Complexity
#

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

Mistakes to Avoid
#

  • An empty tree serializes to an empty string; "".split(",") gives [""] and int("") fails, so check first.
  • Serialize in pre-order (or post-order), never in-order.
  • Do not split the array at each level to find the boundary; that is O(n^2) in the worst case.

Interview Explanation
#

Since it is a BST, I store only the pre-order values with no null markers. To deserialize, the first value is the root and I recurse with bounds: if the next value is out of range I return null and let an ancestor take it; the left subtree’s upper bound and the right subtree’s lower bound are the root’s value. Each value is read once, so time is O(n).

Related

LeetCode 297: Serialize and Deserialize Binary Tree
·2 mins
LeetCode Hard String Tree Depth-First-Search Breadth-First-Search Design Binary-Tree
LeetCode 297 note: pre-order with null markers identifies the tree uniquely; deserialize by consuming tokens from an iterator
LeetCode 99: Recover Binary Search Tree
·2 mins
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 99 note: find the inversions in the in-order sequence: the earlier node of the first inversion and the later node of the last one were swapped
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 173: Binary Search Tree Iterator
·2 mins
LeetCode Medium Stack Tree Design Binary-Search-Tree Binary-Tree Iterator
LeetCode 173 note: flattening to an array is simple but uses O(n) space; the follow-up keeps the left spine on a stack for amortized O(1) and O(h) space
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