1. Naive Cycle Search from Every Vertex via DFS
Intuition
Start a separate DFS traversal from every single vertex with a local path visited set to check if any path loops back to the start.
Algorithm
- Build directed adjacency list where
b -> a. - For each vertex
ifrom0tonumCourses - 1: - Maintain a
visitedset for the current path search. - Perform DFS from
i. - If DFS encounters a node currently in
visited, a cycle exists -> returnfalse. - If no cycle is found from any starting vertex, return
true.
#include <iostream>#include <vector> class Solution { bool hasCycle(int u, const std::vector<std::vector<int>>& adj, std::vector<bool>& onPath) { onPath[u] = true; for (int v : adj[u]) { if (onPath[v]) return true; // Cycle detected if (hasCycle(v, adj, onPath)) return true; } onPath[u] = false; return false; }public: bool canFinish(int numCourses, std::vector<std::vector<int>>& prerequisites) { std::vector<std::vector<int>> adj(numCourses); for (const auto& p : prerequisites) { adj[p[1]].push_back(p[0]); // p[1] -> p[0] } for (int i = 0; i < numCourses; ++i) { std::vector<bool> onPath(numCourses, false); if (hasCycle(i, adj, onPath)) return false; } return true; }}; int main() { Solution sol; std::vector<std::vector<int>> p1 = {{1, 0}}; std::cout << "Can finish p1: " << (sol.canFinish(2, p1) ? "true" : "false") << " (Expected: true)\n"; std::vector<std::vector<int>> p2 = {{1, 0}, {0, 1}}; std::cout << "Can finish p2: " << (sol.canFinish(2, p2) ? "true" : "false") << " (Expected: false)\n"; return 0;}Time & Space Complexity
- Time complexity:
O(V * (V + E)) - Space complexity:
O(V + E)