Serialize and Deserialize Binary Tree

HardBinary Tree · Design (DFS / BFS)🧩 Tree DFSLeetCode #297 ↗Updated

Problem

Design a Codec: serialize(root) turns a binary tree (possibly empty) into a string, deserialize(data) rebuilds the identical tree. Any format is fine.
Input[1,2,3,null,null,4,5]Outputsame tree
Input[]Output[]

0 ≤ n ≤ 104  ·  -1000 ≤ Node.val ≤ 1000  ·  codec must be stateless

Try it yourself

Java
class Codec {
    public String serialize(TreeNode root) {
        
    }

    public TreeNode deserialize(String data) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
A traversal that also records null children (#) fixes the shape; replay it to rebuild.
PatternTree DFS

Instinct If the answer for a node can be built from the answers of its left and right subtrees, write one recursive function and trust it on the children.

Memory hack Ask the kids, then decide - each child reports up, the parent combines, and a global variable keeps the best "bend" seen so far.

Open the Tree DFS guide →

Approaches

Brute ForceHeap-Indexed Array (Complete-Tree Slots)

Time O(2h)Space O(2h)

Heap layout: slot i has children 2i+1, 2i+2. Write all 2h-1 slots (# = empty); a skewed tree wastes almost all of them.

Java
class Codec {
    public String serialize(TreeNode root) {
        String[] slots = new String[(1 << height(root)) - 1];
        Arrays.fill(slots, "#");
        fill(root, 0, slots);
        return String.join(",", slots);
    }
    private int height(TreeNode t) {
        return t == null ? 0 : 1 + Math.max(height(t.left), height(t.right));
    }
    private void fill(TreeNode t, int i, String[] s) {
        if (t == null) return;
        s[i] = String.valueOf(t.val);
        fill(t.left, 2 * i + 1, s); fill(t.right, 2 * i + 2, s);
    }
    public TreeNode deserialize(String data) {
        return data.isEmpty() ? null : build(data.split(","), 0);
    }
    private TreeNode build(String[] s, int i) {
        if (i >= s.length || s[i].equals("#")) return null;
        return new TreeNode(Integer.parseInt(s[i]), build(s, 2 * i + 1), build(s, 2 * i + 2));
    }
}

Fine for balanced trees; explodes (and overflows int indices) on deep ones.

At a glance

LevelApproachTimeSpace
Brute ForceHeap-Indexed Array (Complete-Tree Slots)O(2h)O(2h)
BetterBFS Level Order with Null MarkersO(n)O(n)
OptimalDFS Preorder with Null MarkersO(n)O(n)
Common pitfalls
  • No null markers — 1,2 can't say which child 2 is.
  • No separator — 12 could be one node or two.
  • s += ... in a loop is O(n2); use StringBuilder.
Interview tips
  • Ask about value range and size — they drive the format.
  • Explain why it is unambiguous: 2n+1 tokens, nulls included.
  • Offer BFS to avoid deep recursion on skewed trees.
Pattern
Traversal with null sentinels → encode tree shape losslessly; decode by replaying the traversal.
My notes saved in this browser