for (size_t i = 0; i < num_courses; ++i) { if (degree[i] == 0) { visited++; queue.push(i); } }
while (!queue.empty()) { int32_t cur = queue.front(); queue.pop(); for (constauto& next : neighbors[cur]) { if (--degree[next] == 0) { visited++; queue.push(next); } } }
for (size_t i = 0; i < num_courses; ++i) { if (degree[i] == 0) { visited++; queue.push(i); order.push_back(i); } }
while (!queue.empty()) { int32_t cur = queue.front(); queue.pop(); for (constauto& next : neighbors[cur]) { if (--degree[next] == 0) { visited++; queue.push(next); order.push_back(next); } } }
return (visited == num_courses) ? order : std::vector<int32_t>(); } };
// Check if this is a complete order bool complete = (order.size() == degree.size()); if (complete) { orders.push_back(order); } else { // Explore neighbors for (constauto neighbor : neighbors[candidate]) { if (--degree[neighbor] == 0) { candidates.insert(neighbor); } }
// Backtrack order.pop_back(); candidates.insert(candidate); if (!complete) { for (constauto neighbor : neighbors[candidate]) { if (++degree[neighbor] == 1) { candidates.erase(neighbor); } } } } } };
3 Tiktok Interview Problem
The task is to implement an algorithm to generate all possible valid topological orderings of a Directed Acyclic Graph (DAG).
A Directed Acyclic Graph (DAG) consists of nodes connected by directed edges, with no cycles present. Each node has a unique identifier (id) and may have directed edges pointing to other nodes (neighbors).
Input:
A list of nodes in the graph (graph), where each node contains:
An integer id representing the node’s unique identifier.
A list of neighbors that the current node points to.
Output:
All valid topological orderings of the graph, where:
A topological ordering is a linear ordering of the graph’s nodes such that for every directed edge u -> v, node u appears before node v in the ordering.
// Check if this is a complete order bool complete = (path.size() == graph.size()); if (complete) { paths.push_back(path); } else { // Explore neighbors for (auto* neighbor : node.neighbors) { if (--degree[neighbor->id] == 0) { candidates.insert(neighbor->id); } }
visit(graph, paths, path, degree, candidates); }
// Backtrack path.pop_back(); candidates.insert(node.id); if (!complete) { for (auto* neighbor : node.neighbors) { if (++degree[neighbor->id] == 1) { candidates.erase(neighbor->id); } } } } }
voidprintAll(std::vector<DirectedGraphNode>& graph){ std::set<int32_t> all_ids; std::vector<int32_t> degree(graph.size(), 0); for (auto& node : graph) { all_ids.insert(node.id); for (auto* next : node.neighbors) { degree[next->id]++; } }
std::vector<std::vector<int32_t>> paths; std::vector<int32_t> path; std::set<int32_t> candidates; for (constauto id : all_ids) { if (degree[id] == 0) { candidates.insert(id); } } visit(graph, paths, path, degree, candidates);