Last active
September 24, 2020 06:01
-
-
Save magicoder10/1794b73dd1318ce53062a36b8443c4ce to your computer and use it in GitHub Desktop.
Critical connection
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Solution { | |
public List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) { | |
// write your code here | |
List<List<Integer>> bridges = new LinkedList<>(); | |
if (n < 1 || connections == null || connections.size() < 1) { | |
return bridges; | |
} | |
// 1. Create edge set | |
// 2. Build Graph | |
// 3. dfs | |
// 4. Return edges | |
HashSet<Long> edges = getEdges(n, connections); | |
HashMap<Integer, List<Integer>> graph = buildGraph(n, edges); | |
HashMap<Integer, Integer> ranks = new HashMap<>(); | |
removeCycles(n, graph, 0, ranks, 0, edges); | |
for (long edgeKey : edges) { | |
Edge edge = Edge.fromKey(n, edgeKey); | |
List<Integer> edgeRow = new ArrayList<>(); | |
edgeRow.add(edge.from); | |
edgeRow.add(edge.to); | |
Collections.sort(edgeRow); | |
bridges.add(edgeRow); | |
} | |
return bridges; | |
} | |
private int removeCycles(int n, HashMap<Integer, List<Integer>> graph, int node, HashMap<Integer, Integer> ranks, int depth, HashSet<Long> edges) { | |
if (ranks.containsKey(node)) { | |
return ranks.get(node); | |
} | |
ranks.put(node, depth); | |
int minRank = n; | |
for (int neighbor: graph.get(node)) { | |
if (ranks.containsKey(neighbor) && ranks.get(neighbor) == depth - 1) { | |
continue; | |
} | |
int rank = removeCycles(n, graph, neighbor, ranks, depth + 1, edges); | |
if (rank <= depth) { | |
edges.remove(Edge.getKey(node, neighbor, n)); | |
edges.remove(Edge.getKey(neighbor, node, n)); | |
minRank = Math.min(minRank, rank); | |
} | |
} | |
return Math.min(minRank, depth); | |
} | |
private HashMap<Integer, List<Integer>> buildGraph(int n, HashSet<Long> edges) { | |
HashMap<Integer, List<Integer>> graph = new HashMap<>(); | |
for (long edgeKey: edges) { | |
Edge edge = Edge.fromKey(n, edgeKey); | |
addEdge(graph, edge.from, edge.to); | |
addEdge(graph, edge.to, edge.from); | |
} | |
return graph; | |
} | |
private void addEdge(HashMap<Integer, List<Integer>> graph, int from, int to) { | |
List<Integer> neighbors = graph.getOrDefault(from, new LinkedList<>()); | |
neighbors.add(to); | |
graph.put(from, neighbors); | |
} | |
private HashSet<Long> getEdges(int n, List<List<Integer>> connections) { | |
HashSet<Long> edges = new HashSet<>(); | |
for (List<Integer> connection: connections) { | |
int from = connection.get(0); | |
int to = connection.get(1); | |
edges.add(Edge.getKey(from, to, n)); | |
} | |
return edges; | |
} | |
private static final class Edge { | |
int from; | |
int to; | |
Edge(int from, int to) { | |
this.from = from; | |
this.to = to; | |
} | |
static Edge fromKey(int n, long key) { | |
int from = (int)(key / n); | |
int to = (int)(key % n); | |
return new Edge(from, to); | |
} | |
static long getKey(int from, int to, int n) { | |
return (long)from * n + to; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment