2015年11月15日星期日

Detect Cycle in a Directed Graph

Detect Cycle in a Directed Graph

Given a directed graph, check whether the graph contains a cycle or not. Your function should return true if the given graph contains at least one cycle, else return false. For example, the following graph contains three cycles 0->2->0, 0->1->2->0 and 3->3, so your function must return true.
Solution
Depth First Traversal can be used to detect cycle in a Graph. DFS for a connected graph produces a tree. There is a cycle in a graph only if there is a back edge present in the graph. A back edge is an edge that is from a node to itself (selfloop) or one of its ancestor in the tree produced by DFS. In the following graph, there are 3 back edges, marked with cross sign. We can observe that these 3 back edges indicate 3 cycles present in the graph.

import java.util.ArrayList;
import java.util.List;

public class Solution {
int n;
public List<List<Integer>> adjList = new ArrayList<>();

public Solution(int n) {
this.n = n;
for (int i = 0; i < n; i++) {
adjList.add(new ArrayList<>());
}
}

public void addEdge(int from, int to) {
adjList.get(from).add(to);
}

public boolean hasCycle() {
boolean[] visited = new boolean[n];
boolean[] inStack = new boolean[n];
for (int i = 0; i < n; i++) {
if (!visited[i]) {
if (dfsCycle(i, visited, inStack)) {
return true;
}
}
}
return false;
}

private boolean dfsCycle(int start, boolean[] visited, boolean[] inStack) {
visited[start] = true;
inStack[start] = true;
for (int next : adjList.get(start)) {

if (!visited[start] && dfsCycle(next, visited, inStack)) {
return true;
} else if (inStack[next]) {
return true;
}
}
inStack[start] = false;
return false;
}

public static void main(String args[]) {
Solution g = new Solution(4);
g.addEdge(0, 1);
   g.addEdge(0, 2);
   g.addEdge(1, 2);
   g.addEdge(2, 0);
   g.addEdge(2, 3);
   g.addEdge(3, 3);
   System.out.println(g.hasCycle());
}
}

没有评论:

发表评论