03
Distance / minimum depth (Tree BFS Sub-pattern)
Use BFS's "closest first" order: stop at the first leaf, or spread out from a node in every direction (adding parent links to go up).
Signals in the problem statement
- ›
"minimum depth" / "nearest leaf"
- ›
"all nodes at distance K from target"
- ›
"infection spreads to neighbours each minute"
What makes it different
Minimum Depth is plain level BFS that returns at the first leaf. It is not 1 + min(left, right), because a missing child isn't a leaf. All Nodes Distance K first builds a parent map, then BFS from the target for exactly k rounds with a visited set. Infection Time is the same graph BFS from the start node, run until the queue is empty; the answer is the number of rounds minus one, because minute 0 is the start node itself.
Questions
ordered from “learn the idea” to “recognise it without help”- 1Minimum Depth of Binary TreeWalkthroughEasyBasic Anchor·LeetCode #111
- 2All Nodes Distance K in Binary TreeWalkthroughMediumMedium·LeetCode #863
- 3Amount of Time for Binary Tree to Be InfectedWalkthroughMediumInterview-Level·LeetCode #2385
Template
bfs-distance-template.cpp
// Distance from a start node in every direction: add parent links, then BFS like a graph.
// Returns the values of all nodes exactly k edges away from start.
vector<int> nodesAtDistance(TreeNode* root, TreeNode* start, int k) {
unordered_map<TreeNode*, TreeNode*> parent;
function<void(TreeNode*)> link = [&](TreeNode* node) {
for (TreeNode* child : {node->left, node->right})
if (child) { parent[child] = node; link(child); }
};
if (root) link(root);
queue<TreeNode*> q;
unordered_set<TreeNode*> seen{start}; // without this we walk straight back where we came from
q.push(start);
for (int dist = 0; !q.empty(); dist++) {
if (dist == k) { // everything in the queue is exactly k away
vector<int> out;
while (!q.empty()) { out.push_back(q.front()->val); q.pop(); }
return out;
}
int size = q.size();
for (int i = 0; i < size; i++) {
TreeNode* node = q.front(); q.pop();
TreeNode* up = parent.count(node) ? parent[node] : nullptr;
for (TreeNode* nb : {node->left, node->right, up})
if (nb && seen.insert(nb).second) q.push(nb);
}
}
return {};
}Remember this · Tree BFS
Trigger
Level order, per-level max/average, right side view, minimum depth, nodes at distance k.
Think
Does the question care about depth / rows rather than paths?
Key question
How many nodes are in the current level (queue size at the start of the level)?