Skip to main content

297. Serialize and Deserialize Binary Tree

hardAsked at Microsoft

Serialize and Deserialize Binary Tree is Microsoft's litmus test for whether you can design a custom encoding and parse it back. The pre-order DFS with explicit null markers is the standard answer; the interviewer is grading whether your serializer and deserializer agree on exactly how nulls are represented.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Microsoft loops.

  • Glassdoor (2026-Q1)Microsoft Azure org senior onsite reports list Serialize/Deserialize as a 45-minute design-and-implement hard.
  • Blind (2025-12)Multiple Microsoft L62/L63 interview compilations include this question with the 'now make it compact' twist.

Problem

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

Constraints

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

Examples

Example 1

Input
root = [1,2,3,null,null,4,5]
Output
[1,2,3,null,null,4,5]

Example 2

Input
root = []
Output
[]

Approaches

1. Pre-order DFS with null markers (optimal)

Serialize: pre-order traversal, emit each value (or 'N' for null) separated by commas. Deserialize: split, then consume tokens one at a time recursively.

Time
O(n) each direction
Space
O(n) for the string + recursion
function serialize(root) {
  const out = [];
  function dfs(node) {
    if (!node) { out.push('N'); return; }
    out.push(String(node.val));
    dfs(node.left);
    dfs(node.right);
  }
  dfs(root);
  return out.join(',');
}

function deserialize(data) {
  const tokens = data.split(',');
  let i = 0;
  function build() {
    if (tokens[i] === 'N') { i++; return null; }
    const node = { val: Number(tokens[i++]), left: null, right: null };
    node.left = build();
    node.right = build();
    return node;
  }
  return build();
}

Tradeoff: Pre-order is the right traversal because the first token is always the root of the (sub)tree being built — the recursion can consume tokens linearly. In-order alone is insufficient because you can't tell where the left subtree ends without the structure.

2. Level-order BFS (LeetCode-style array)

BFS through the tree, emitting each node's value (or null marker). Deserialize by pairing children to parents level by level using a queue.

Time
O(n)
Space
O(n)
function serialize(root) {
  if (!root) return '';
  const out = [];
  const queue = [root];
  while (queue.length) {
    const node = queue.shift();
    if (!node) { out.push('N'); continue; }
    out.push(String(node.val));
    queue.push(node.left);
    queue.push(node.right);
  }
  return out.join(',');
}

function deserialize(data) {
  if (!data) return null;
  const tokens = data.split(',');
  const root = { val: Number(tokens[0]), left: null, right: null };
  const queue = [root];
  let i = 1;
  while (queue.length && i < tokens.length) {
    const node = queue.shift();
    if (tokens[i] !== 'N') {
      node.left = { val: Number(tokens[i]), left: null, right: null };
      queue.push(node.left);
    }
    i++;
    if (i < tokens.length && tokens[i] !== 'N') {
      node.right = { val: Number(tokens[i]), left: null, right: null };
      queue.push(node.right);
    }
    i++;
  }
  return root;
}

Tradeoff: Matches LeetCode's display format, which is sometimes useful for debugging. Slightly trickier to parse because each iteration consumes exactly two tokens (left, right) per parent.

Microsoft-specific tips

Microsoft is grading the consistency between your serializer and deserializer. Before writing either, write the format spec out loud: 'I'm using comma-separated tokens; each value is the node's integer value; nulls are the literal string N; pre-order means root, left subtree, right subtree.' That spec is what holds the two halves together — they always either both work or both break the same way.

Common mistakes

  • Using only in-order (or only post-order) without null markers — ambiguous structure.
  • Using a delimiter that can appear in node values (e.g., '-' fails when values can be negative).
  • In the BFS version, advancing the queue but forgetting to advance the index for the null branches.

Follow-up questions

An interviewer at Microsoft may pivot to one of these next:

  • Serialize/Deserialize BST (LC 449) — exploit BST ordering to drop the null markers.
  • Serialize/Deserialize N-ary Tree (LC 428).
  • What if the values could be arbitrary strings? Quote them, escape delimiters.

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why pre-order and not in-order?

Pre-order writes the root first, so deserialize knows what to build at each step. With in-order and no structural markers, you can't tell where the left subtree ends.

Is the null marker really necessary?

Yes — without it, multiple distinct trees produce the same traversal output. The null marker is what makes the encoding lossless.

Free learning resources

Curated free links for this problem.

Practice these live with InterviewChamp.AI

Drill Serialize and Deserialize Binary Tree and other Microsoft interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →