-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcourse_schedule.php
77 lines (61 loc) · 2.1 KB
/
course_schedule.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<?php
/**
* Course Schedule
* @link https://leetcode.com/problems/course-schedule
*
* Approach:
* If there is a cycle in given graph, then we can't complete all courses, so we need to detect is there a cycle in given graph.
* For detecting cycle in a graph, we can use simple DFS traverse with set/hash-map to keep track of visited nodes.
* If node is already visited then - there is a cycle.
*
* Or we can use BFS solution that I like better.
* For detecting cycle in a graph using BFS we can use Kanh's algorithm for topological sort.
*
* Time Complexity - O(V + E)
* Space Complexity - O(V + E)
*/
class Solution {
public function canFinish($numCourses, $prerequisites)
{
$adjacencyList = $this->buildAdjacencyList($numCourses, $prerequisites);
return !$this->hasCycle($adjacencyList);
}
private function hasCycle($graph)
{
$inDegreeOfNodes = array_fill(0, count($graph), 0);
for ($i = 0; $i < count($graph); $i++) {
for ($j = 0; $j < count($graph[$i]); $j++) {
$inDegreeOfNodes[$graph[$i][$j]]++;
}
}
$queue = new SplQueue();
for ($i = 0; $i < count($graph); $i++) {
if ($inDegreeOfNodes[$i] === 0) {
$queue->enqueue($i);
}
}
$visitedNodesCount = 0;
while (!$queue->isEmpty()) {
$node = $queue->dequeue();
$visitedNodesCount++;
for ($i = 0; $i < count($graph[$node]); $i++) {
$inDegreeOfNodes[$graph[$node][$i]]--;
if ($inDegreeOfNodes[$graph[$node][$i]] === 0) {
$queue->enqueue($graph[$node][$i]);
}
}
}
return count($graph) !== $visitedNodesCount;
}
private function buildAdjacencyList($nodesCount, $edges)
{
$adjacencyList = [];
for ($i = 0; $i < $nodesCount; $i++) {
$adjacencyList[$i] = [];
}
for ($i = 0; $i < count($edges); $i++) {
$adjacencyList[$edges[$i][0]][] = $edges[$i][1];
}
return $adjacencyList;
}
}