</> MAANG.io
coding interview ยท 101

Foundations

Master coding interviews with comprehensive coverage of data structures, algorithms, and problem-solving techniques. Progress from fundamentals to advanced topics with expertly curated content.

0/255 solved 0% complete

Build and Serialize

What is this?

So far we've been reading trees โ€” here we make them. That means building a new tree, drawing one out as a picture, or flattening one into a line of text so it can be saved or sent and then rebuilt later, exactly. It's like writing down assembly instructions for a piece of furniture so detailed that someone on the other side of the world can recreate it piece for piece. The secret is choosing an order to record things in that leaves zero ambiguity.

flowchart TD A["Have a tree"] --> B["Pick an unambiguous order"] B --> C["Emit or place each node"] C --> D["Rebuild by replaying the order"]

๐Ÿ’ก Fun fact: Turning a tree into a string is called "serialization," the same idea that lets your browser save a web page or a game save your progress to disk. The make-or-break detail is recording the empty spots too โ€” without those blank markers, many different trees would flatten to the same text and could never be told apart.

๐Ÿ”“ The 3 problems in this chapter are free. Sign in with Google or Microsoft to start solving.


Core idea: These problems are about producing a tree or a representation of one, rather than just reading it. The unifying move is a recursive walk where structure drives the work: visit nodes in a fixed order, and let each node's position in the recursion tell you what to create, where to place it, or what to write down. Get the order and the position right, and building mirrors traversing.


The pattern

Construction is traversal run in reverse. When you read a tree you consume its nodes in some order; when you build or encode one, you emit or place nodes in that same order. The trick is choosing an order that is unambiguous โ€” that lets you (or a later reader) recover exactly one tree.

Two reliable orders show up here. Parallel DFS walks two trees at once, pairing up nodes by identical position so you can combine them. Position-by-formula uses the fact that in a perfect binary tree a node's row and column are computable from its depth, so you can drop nodes into a grid without any extra bookkeeping. And for full round-tripping, preorder with explicit null markers records enough about the shape that decoding becomes a straightforward replay.


The problems

  • Merge Two Binary Trees โ€” parallel DFS: recurse on both trees together; where both have a node, sum them; where only one does, splice that subtree in wholesale.
  • Print Binary Tree โ€” compute the output grid's height and width from the tree's depth, then place each node at the column its position formula dictates so the layout reads like a real tree.
  • Serialize and Deserialize Binary Tree โ€” preorder DFS writing values plus null placeholders, so the marker stream encodes the shape; deserialize replays that stream in the same preorder to rebuild it.

Key takeaways

  • Building is traversal in reverse โ€” pick a node order that uniquely determines the tree, then emit or place in that order.
  • Parallel DFS handles any "combine two trees by position" task in one pass.
  • Null markers are what make a flat string round-trip โ€” they carry the structure that values alone would lose.
  • Why interviewers like it: serialization forces you to reason about what information uniquely identifies a tree, a deeper test than a plain traversal.

Order: Merge Two Binary Trees โ†’ Print Binary Tree โ†’ Serialize and Deserialize Binary Tree โ†’ Construct Binary Tree from Preorder and Inorder โ†’ Construct Binary Tree from Inorder and Postorder.

Print Binary Tree

Core idea: Size a fixed grid from the tree's height, drop the root in the dead center of the top row, then place each child a halving horizontal offset to the left or right one row down.


Problem, rephrased

You're building the layout engine for a diagram tool. Someone hands you a binary tree and you must lay it out on a fixed-width character grid so that every node sits visually between and below its parent โ€” the classic "centered tree" look you see in textbooks and org charts.

Concretely, you produce a 2D matrix of strings (List[List[str]]):

  • Let h be the height of the tree (height of a single node = 0).
  • The matrix has h + 1 rows and 2^(h+1) - 1 columns.
  • The root goes in the middle column of row 0.
  • A node at position (r, c) places:
    • its left child at (r+1, c - 2^(h-r-1))
    • its right child at (r+1, c + 2^(h-r-1))
  • Every cell that has no node is the empty string "".

Inputs / outputs

Input tree Height h Rows ร— Cols Output matrix
1 (single node) 0 1 ร— 1 [["1"]]
1 with children 2,3 1 2 ร— 3 [["","1",""],["2","","3"]]
1 โ†’ left 2, 2 โ†’ right 4 2 3 ร— 7 see below

That last tree:

Input tree: root 1 with left child 2, whose right child is 4

lays out as a 3 ร— 7 grid:

col:  0    1    2    3    4    5    6
row0  ""   ""   ""   "1"  ""   ""   ""
row1  ""   "2"  ""   ""   ""   ""   ""
row2  ""   ""   "4"  ""   ""   ""   ""

Notice how sparse it is โ€” a lopsided tree wastes most of the grid, but the shape is faithfully preserved.


Sign in to continue reading

The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.

Sign in to read the full lesson

Sign in to MAANG.io

Use your Google or Microsoft account โ€” no password to remember.

Continue with Google Continue with Microsoft

Please accept the terms above to continue.