1
+ def hasCycle (edges , numEdges ):
2
+ #Initialize a graph that stores the neighbor of each node
3
+ graph = {i :[] for i in list (range (numEdges ))}
4
+ #Populate the graph so that the 'children' of each node are stored with the parent as the key
5
+ for x , y in edges : graph [x ] += [y ]
6
+ #Create three sets, one to store all unvisited nodes, one to store nodes curently visiting, one to store completely visited ones
7
+ unvisited = list (range (numEdges ))
8
+ visiting = set ()
9
+ completelyVisited = set ()
10
+
11
+ #While we still have nodes that are unvisited
12
+ while unvisited :
13
+ #We graph a random node from the unvisited collection to run a DFS on
14
+ currentNode = unvisited [0 ]
15
+ #If a call to the depth first seach returns true then we know this graph has a cycle and can return true
16
+ if depthFirstSearch (currentNode , unvisited , visiting , completelyVisited , graph ): return True
17
+ #If no call to the depth first search returns true then we can return False that there is no cycle in this graph
18
+ return False
19
+
20
+ #Define our helper depth first search for a cycle
21
+ def depthFirstSearch (currentNode , unvisited , visiting , completelyVisited , graph ):
22
+ #Firstly, we need to move the current node we're at from unvisited and to visiting
23
+ unvisited .remove (currentNode )
24
+ visiting .add (currentNode )
25
+ #Now for each of this nodes adjacent neighbors we need to run this DFS again
26
+ for neighbor in graph [currentNode ]:
27
+ #If that neighbor has already been completely visited, we can skip tis particular neighbor
28
+ if neighbor in completelyVisited : continue
29
+ #If this neighbor is already a node we're visiting then return true that this has a cycle! Because we've circled back to a parent node
30
+ if neighbor in visiting : return True
31
+ #If any its neighbors have a cycle return true as well
32
+ if depthFirstSearch (neighbor , unvisited , visiting , completelyVisited , graph ): return True
33
+ #Finally remove this current node from visiting and add it to completely visited
34
+ visiting .remove (currentNode )
35
+ completelyVisited .add (currentNode )
36
+
37
+ def main ():
38
+ print (hasCycle ([[1 , 0 ], [0 , 2 ]], 3 ))
39
+
40
+ main ()
0 commit comments