1. Null marker
A sentinel for empty children makes the encoding unambiguous.
parts.push("#")Typorithm · hard
Step 1 of 8 · intro card
Trees
Pre-order DFS emits each node with '#' for nulls; deserialize consumes the same token stream to rebuild the exact tree.
Serializing must capture both values and shape, so null children get an explicit '#' marker.
A pre-order DFS writes node, then left subtree, then right subtree, into a comma-joined string.
Deserialize consumes tokens in that same order, recursing to rebuild left and right, recreating the original tree.
Pre-order with null markers.
'#' encodes an empty child.
Rebuild reads tokens in the same order.
function serialize(root) {
const parts = [];
function dfs(node) {
if (node === null) {
parts.push("#");
return;
}
parts.push(String(node.val));
dfs(node.left);
dfs(node.right);
}
dfs(root);
return parts.join(",");
}
function deserialize(data) {
const parts = data.split(",");
let i = 0;
function build() {
const token = parts[i];
i += 1;
if (token === "#") {
return null;
}
const node = { val: Number(token), left: null, right: null };
node.left = build();
node.right = build();
return node;
}
return build();
}Connect each part of the code to the concept before you type.
A sentinel for empty children makes the encoding unambiguous.
parts.push("#")Record the node before recursing, capturing structure.
parts.push(String(node.val));
dfs(node.left);
dfs(node.right)Rebuild reads tokens in the same pre-order sequence.
const token = parts[i];
i += 1Recursion reconstructs left then right, mirroring serialize.
node.left = build();
node.right = build()Read the concept map and follow the code breakdown.
Type the implementation, repair mistakes and work through every recall exercise.
Use the final check without hints; revisit weak concepts in short practice sessions.