{"id":22513865,"url":"https://github.com/emahtab/course-schedule","last_synced_at":"2026-01-08T04:03:17.138Z","repository":{"id":79525387,"uuid":"247328347","full_name":"eMahtab/course-schedule","owner":"eMahtab","description":"Course Schedule","archived":false,"fork":false,"pushed_at":"2025-01-15T04:04:55.000Z","size":25,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-02T03:25:46.084Z","etag":null,"topics":["bfs","dfs","kosaraju-algorithm","leetcode","problem-solving","strongly-connected-components","topological-sort"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eMahtab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-14T18:08:00.000Z","updated_at":"2025-01-15T04:04:56.000Z","dependencies_parsed_at":"2025-02-02T03:25:29.697Z","dependency_job_id":"01e94cea-be4f-4fa8-8350-de8e6ce63e03","html_url":"https://github.com/eMahtab/course-schedule","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eMahtab%2Fcourse-schedule","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eMahtab%2Fcourse-schedule/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eMahtab%2Fcourse-schedule/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eMahtab%2Fcourse-schedule/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eMahtab","download_url":"https://codeload.github.com/eMahtab/course-schedule/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245952143,"owners_count":20699437,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bfs","dfs","kosaraju-algorithm","leetcode","problem-solving","strongly-connected-components","topological-sort"],"created_at":"2024-12-07T03:14:44.795Z","updated_at":"2026-01-08T04:03:12.109Z","avatar_url":"https://github.com/eMahtab.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Course Schedule\n## https://leetcode.com/problems/course-schedule\n\nThere are a total of numCourses courses you have to take, labeled from 0 to numCourses-1.\n\nSome courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]\n\nGiven the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?\n\n```\nExample 1:\n\nInput: numCourses = 2, prerequisites = [[1,0]]\nOutput: true\nExplanation: There are a total of 2 courses to take. \n             To take course 1 you should have finished course 0. So it is possible.\nExample 2:\n\nInput: numCourses = 2, prerequisites = [[1,0],[0,1]]\nOutput: false\nExplanation: There are a total of 2 courses to take. \n             To take course 1 you should have finished course 0, and to take course 0 you should\n             also have finished course 1. So it is impossible.\n``` \n\n**Constraints:**\n\n1. The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.\n2. You may assume that there are no duplicate edges in the input prerequisites.\n3. 1 \u003c= numCourses \u003c= 10^5\n\n# Approach :\nPush a course to stack only when all its prerequisites are completed, which means If indegree for this course is 0.\n\nWhile stack is not empty, pop a course from the stack , increment the course completed counter. And also update the indegree of the course for which this current course was a prerequisite. Now if the indegree for any course becomes zero as we update the indegrees, add that course to stack for which indegree reached to zero.\n\nFinally when the stack is empty, the value of the course completed counter should be equal to number of courses If we were able to complete all the courses. But If the value of the course completed counter is not equal to number of courses, it means its not possible to complete all the courses. \n\n## Implementation 1 : DFS (Stack)\n\n```java\nclass Solution {\n    public boolean canFinish(int numCourses, int[][] prerequisites) {\n        int[] inDegrees = new int[numCourses];\n        int count = 0;\n        for(int i = 0; i \u003c prerequisites.length; i++) {\n            inDegrees[prerequisites[i][0]]++;\n        }\n        \n        Stack\u003cInteger\u003e stack = new Stack\u003c\u003e();\n        for(int i = 0; i \u003c inDegrees.length; i++) {\n            if(inDegrees[i] == 0) {\n                stack.push(i);\n            }\n        }\n        \n        while(!stack.isEmpty()) {\n            int course = stack.pop();\n            count++;\n            for(int i = 0; i \u003c prerequisites.length; i++) {\n                if(prerequisites[i][1] == course) {\n                    inDegrees[prerequisites[i][0]]--;\n                    if(inDegrees[prerequisites[i][0]] == 0) {\n                        stack.push(prerequisites[i][0]);\n                    }\n                }\n            }\n        }\n        return numCourses == count;\n    }\n}\n```\n\n## Implementation 2 : BFS (Queue) , Runtime : O(n * m), Space = O(n)\n\nn = number of courses (numCourses)\n\nm = prerequisites.length\n\n```java\nclass Solution {\n    public boolean canFinish(int numCourses, int[][] prerequisites) {\n        int[] inDegrees = new int[numCourses];\n    \n        int count = 0;\n        for(int i = 0; i \u003c prerequisites.length; i++) {\n            inDegrees[prerequisites[i][0]]++;\n        }\n        \n        Queue\u003cInteger\u003e queue = new LinkedList\u003c\u003e();\n        for(int i = 0; i \u003c inDegrees.length; i++) {\n            if(inDegrees[i] == 0) {\n                queue.offer(i);\n            }\n        }\n        \n        while(!queue.isEmpty()) {\n            int course = queue.poll();\n            count++;\n            for(int i = 0; i \u003c prerequisites.length; i++) {\n                if(prerequisites[i][1] == course) {\n                    inDegrees[prerequisites[i][0]]--;\n                    if(inDegrees[prerequisites[i][0]] == 0) {\n                        queue.offer(prerequisites[i][0]);\n                    }\n                }\n            }\n        }\n        return numCourses == count;\n    }\n}\n```\n\n## Implementation 2a (using Adjacency list) : BFS , Runtime = O(n + m), Space = O(n + m)\n\nn = number of courses (numCourses)\n\nm = prerequisites.length\n\n```java\nclass Solution {\n    public boolean canFinish(int numCourses, int[][] prerequisites) {\n        List\u003cList\u003cInteger\u003e\u003e adjacencyList = new ArrayList\u003c\u003e();\n        int[] indegree = new int[numCourses];\n        Queue\u003cInteger\u003e queue = new ArrayDeque\u003c\u003e();\n        int courseCompleted = 0;\n\n        for(int i = 0; i \u003c numCourses; i++)\n            adjacencyList.add(new ArrayList\u003c\u003e());\n\n        for(int[] prerequisite : prerequisites) {\n            int a = prerequisite[0];\n            int b = prerequisite[1];\n            indegree[a]++;\n            adjacencyList.get(b).add(a);\n        }\n        for(int i = 0; i \u003c numCourses; i++){\n            if(indegree[i] == 0)\n              queue.offer(i);\n        }\n\n        while(!queue.isEmpty()) {\n            int course = queue.remove();\n            courseCompleted++;\n            for(int neighbor : adjacencyList.get(course)){\n                indegree[neighbor]--;\n                if(indegree[neighbor] == 0)\n                  queue.offer(neighbor);\n            }\n        }\n        return courseCompleted == numCourses;\n    }\n}\n```\n\n# Implementation 3 : Kosaraju's Algorithm (SCC size)\nIdea is to use Kosaraju'a algorithm to find the size of Strongly Connected components (SCC), if we find a SCC whose size is greater than 1, it means it have cycle, in this case return false. And if we don't find any SCC with size greater than 1, it means all the constraints can be fulfilled, and we return true.\n```java\nclass Solution {\n    public boolean canFinish(int numCourses, int[][] prerequisites) {\n        \n        Map\u003cInteger,List\u003cInteger\u003e\u003e graph = new HashMap\u003c\u003e();\n        for(int[] prerequisite : prerequisites) {\n            int u = prerequisite[1];\n            int v = prerequisite[0];\n            if(u == v)\n                return false;\n            graph.putIfAbsent(u, new ArrayList\u003cInteger\u003e());\n            graph.get(u).add(v);\n        }\n        \n        // Kosaraju's algorithm\n        Stack\u003cInteger\u003e stack = new Stack\u003c\u003e();\n        boolean[] visited = new boolean[numCourses];\n        for(int v = 0; v \u003c numCourses; v++) {\n            if(!visited[v]) {\n              dfs1(v,graph,visited,stack);   \n            }\n        }\n        // Transpose the edges\n        Map\u003cInteger,List\u003cInteger\u003e\u003e reversedGraph = new HashMap\u003c\u003e();\n        for(int u : graph.keySet()) {\n            for(int v : graph.get(u)) {\n                reversedGraph.putIfAbsent(v, new ArrayList\u003cInteger\u003e());\n                reversedGraph.get(v).add(u);\n            }\n        }\n        \n        visited = new boolean[numCourses];\n        while(!stack.isEmpty()) {\n            int v = stack.pop();\n            if(!visited[v]) {\n                int size = dfs2(v, reversedGraph, visited);\n                if(size \u003e 1)\n                    return false;\n            }\n        }\n       return true; \n    }\n    \n    private void dfs1(int vertex, Map\u003cInteger,List\u003cInteger\u003e\u003e graph, \n                      boolean[] visited, Stack\u003cInteger\u003e stack) {\n        if(!visited[vertex]) {\n            visited[vertex] = true;\n            List\u003cInteger\u003e neighbors = graph.get(vertex);\n            if(neighbors != null) {\n              for(int neighbor : neighbors) {\n                  dfs1(neighbor,graph,visited,stack);\n              }   \n            }\n            stack.push(vertex);\n        }\n    }\n    \n    private int dfs2(int vertex, Map\u003cInteger,List\u003cInteger\u003e\u003e graph, boolean[] visited) {\n        int size = 0;\n        if(!visited[vertex]) {\n            size++;\n            visited[vertex] = true;\n            List\u003cInteger\u003e neighbors = graph.get(vertex);\n            if(neighbors != null) {\n                for(int neighbor : neighbors) {\n                   size += dfs2(neighbor, graph, visited);\n                }\n            }\n        }\n        return size;\n    }\n}\n```\n\n# References :\n1. https://www.youtube.com/watch?v=0LjVxtLnNOk\n2. https://www.youtube.com/watch?v=z-mB8ZL6mjo (Topological Sort)\n3. https://leetcode.com/problems/course-schedule/discuss/249688/Different-O(V%2BE)-solution-using-Kosaraju's-algorithm\n4. https://github.com/eMahtab/kosaraju-algorithm\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femahtab%2Fcourse-schedule","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femahtab%2Fcourse-schedule","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femahtab%2Fcourse-schedule/lists"}