一键导入
algo-dfs
Depth-first search — recursive vs iterative, recursion-depth gotchas, three-color cycle detection, topological sort.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Depth-first search — recursive vs iterative, recursion-depth gotchas, three-color cycle detection, topological sort.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Breadth-first search — shortest path on unweighted graphs, level-order traversal, and the `visited` discipline that prevents O(2^n) blowups.
Binary search invariants, half-open intervals, and the `lo<hi` template that beats off-by-one bugs.
Dynamic programming — state design, memoization vs tabulation, dimension-reduction, and when DP is the wrong tool.
Pick the right traversal — BFS for unweighted shortest path, Dijkstra for weighted, A* for goal-directed, 0/1-BFS for binary weights.
Greedy algorithms — exchange-argument proofs, when greedy beats DP, classic patterns (interval scheduling, Huffman, scheduling).
Hash maps and sets — when O(1) lookup pays off, hash collisions, frozen keys, and hashing custom types.
| name | algo-dfs |
| description | Depth-first search — recursive vs iterative, recursion-depth gotchas, three-color cycle detection, topological sort. |
| when-to-use | Connected components, topological sort, cycle detection, tree/graph path enumeration, backtracking skeleton. |
DFS is the workhorse behind topological sort, cycle detection, articulation points, SCC, and most backtracking puzzles. Two ways to spell it: recursive (clean) or iterative-with-stack (deep graphs without blowing the recursion limit).
state[v] is one of WHITE (unseen), GRAY (on the current
DFS path), BLACK (fully processed). The three-color invariant
is what lets cycle detection on directed graphs work.u → v: if state[v] == GRAY, you've found a back edge —
the directed graph has a cycle.BLACK re-entry is possible because there are
no cycles.O(V + E) for adjacency-list graphs.O(V) for the recursion stack / explicit stack +
state array.WHITE, GRAY, BLACK = 0, 1, 2
def has_cycle(adj: list[list[int]]) -> bool:
"""True iff the directed graph contains any cycle."""
state = [WHITE] * len(adj)
def dfs(u: int) -> bool:
state[u] = GRAY
for v in adj[u]:
if state[v] == GRAY: return True
if state[v] == WHITE and dfs(v): return True
state[u] = BLACK
return False
for u in range(len(adj)):
if state[u] == WHITE and dfs(u):
return True
return False
The same shape produces a topological order: append u to a list
just before turning BLACK, then reverse the list. (Equivalent to
"emit in post-order, reverse.")
function dfsIterative(start, neighbors) {
const visited = new Set();
const stack = [start];
const order = [];
while (stack.length) {
const u = stack.pop();
if (visited.has(u)) continue;
visited.add(u);
order.push(u);
// Push in reverse so the natural left-to-right order is preserved.
const ns = neighbors(u);
for (let i = ns.length - 1; i >= 0; i--) {
if (!visited.has(ns[i])) stack.push(ns[i]);
}
}
return order;
}
For O(1M) deep graphs prefer the iterative form; recursion will
hit the engine's call-stack limit. Python: sys.setrecursionlimit
buys you headroom but only up to OS thread-stack size (~10K-100K
frames before a SegFault on macOS).
v == parent.sys.setrecursionlimit(10**6) or an iterative rewrite.visited check.u → u) — directed graphs: cycle; undirected: by
convention also a cycle.u → v and v → u) — a
cycle of length 2.When the DFS returns paths, remember to copy the path list before recording it — a Python list passed by reference will mutate as the search continues.