Leetcode: Critical Connections in a Network
This Question is extremely frequently asked at Amazon. Sometimes it is asked at Adobe.
The starting node has rank 0 and all other nodes have a rank of -2. We increase the rank of each node as we move nodes, and then when we find a node with a lesser rank of 0 <= p < k if we are supposed to denote with length k, if a node has rank p, this means that we found a cycle.
Let's have the depth-first-search function return the minimum rank that it finds. If dfs(v) returns something smaller or equal to rank(u), then you know that its neighbor has a cycle, so the edge is subsequently discarded. As a result, the remaining edges are the critical edges.
Here's the code with its explanation and implementation:
class Solution {
int dfs(List<Integer>[] graph, int node, int depth, int[] rank, HashSet<List<Integer>> connectionSet) {
//This node is already visited, no need to visit it again.
if(rank[node] >= 0 ) return rank[node];
//set this rank of the node to the depth
rank[node] = depth;
int minDepthFound = Integer.MAX_VALUE;
//iterate through all the neighbors of this node
for(Integer neighbor : graph[node]) {
//ignore the parent node.
if(rank[neighbor] == depth - 1) continue ;
//perform dfs to have the minimum depth of the neighbor
int minDepth = dfs(graph, neighbor, depth + 1, rank, connectionsSet);
minDepthFound = Math.min(minDepthFound, minDepth);
//If one of the successors of the neighbors has a depth less than current node, then we have a cycle.
if(minDepth <= depth) {
//remove the unnecessary nodes.
connectionsSet.remove(Arrays.asList(node, neighbor));
connectionsSet.remove(Arrays.asList(neighbor, node));
}
}
return minDepthFound;
}
public List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) {
List<Integer> graph = new ArrayList[n];
//initialize an array of ArrayLists that lists the neighbors and connections to the graph.
for(int i = 0; i < n; i++) {
graph[i] = new ArrayList<>();
}
//add each connection of the graph to the corresponding arrayList index
for(List<Integer> oneConnection : connections) {
graph[oneConnection.get(0)].add(oneConnection.get(1));
graph[oneConnection.get(1)].add(oneConnection.get(0));
//convert the connections to a hashset.
HashSet<List<Integer>> connectionsSet = new HashSet<>(connections);
int[] rank = new int[n];
//All the ranks eventually starts with -2
Arrays.fill(rank, -2);
//remove all the critical connections and return this new list.
dfs(graph, 0, 0, rank, connectionsSet);
return new ArrayList<>(connectionsSet);
}
}
This problem has O(|V| + |E|) time complexity.


Comments
Post a Comment