Connected Component in Undirected Graph
Given graph:
A------B C
\ | |
\ | |
\ | |
\ | |
D E
Return {A,B,D}, {C,E}. Since there are two connected component which is {A,B,D}, {C,E}Given graph:
A------B C
\ | |
\ | |
\ | |
\ | |
D E
Return {A,B,D}, {C,E}. Since there are two connected component which is {A,B,D}, {C,E} /**
* Definition for Undirected graph.
* class UndirectedGraphNode {
* int label;
* ArrayList<UndirectedGraphNode> neighbors;
* UndirectedGraphNode(int x) { label = x; neighbors = new ArrayList<UndirectedGraphNode>(); }
* };
*/
public class Solution {
/**
* @param nodes a array of Undirected graph node
* @return a connected set of a Undirected graph
*/
public List<List<Integer>> connectedSet(ArrayList<UndirectedGraphNode> nodes) {
// 对每一个node进行bfs,每次bfs得到的结果就是一个component,同时在visited中标记即可
List<List<Integer>> res = new ArrayList<>();
if (nodes == null || nodes.size() == 0) {
return res;
}
Set<UndirectedGraphNode> visited = new HashSet<>();
for (UndirectedGraphNode node : nodes) {
bfs(node, visited, res);
}
// 这部分排序其实不必要
Collections.sort(res, new Comparator<List<Integer>>(){
public int compare(List<Integer> lst1, List<Integer> lst2) {
if (lst1.get(0) < lst2.get(0)) return -1;
if (lst1.get(0) == lst2.get(0)) return 0;
else return 1;
}
});
return res;
}
private void bfs(UndirectedGraphNode node, Set<UndirectedGraphNode> visited,
List<List<Integer>> res) {
if (visited.contains(node)) return;
Deque<UndirectedGraphNode> queue = new LinkedList<>();
List<Integer> component = new ArrayList<>();
component.add(node.label);
queue.addFirst(node);
visited.add(node);
while (! queue.isEmpty()) {
node = queue.removeLast();
for (UndirectedGraphNode neighbor : node.neighbors) {
if (visited.contains(neighbor)) continue;
queue.addFirst(neighbor);
visited.add(neighbor);
component.add(neighbor.label);
}
}
Collections.sort(component);
res.add(component);
}
} # Union Find Algorithm
class Solution:
# @param {UndirectedGraphNode[]} nodes a array of undirected graph node
# @return {int[][]} a connected set of a undirected graph
def connectedSet(self, nodes):
def find(x):
while ids[x] != x:
ids[x] = find(ids[x])
x = ids[x]
return x
def union(x, y):
rootx = find(x)
rooty = find(y)
if rootx == rooty:
return
if rank[rootx] < rank[rooty]:
ids[rootx] = rooty
elif rank[rootx] > rank[rooty]:
ids[rooty] = rootx
else:
ids[rootx] = rooty
rank[rooty] += 1
# initialize Union-Find
ids = [i for i in range(len(nodes))]
rank = [0 for i in range(len(nodes))]
# 将node和id 一一对应
# 只需要存储node:id的对应,id:node的对应在nodes中是原生的
# 因为id就是node在nodes中的index
nodeId = {}
for i in range(len(nodes)):
nodeId[nodes[i]] = i
# do union find
for node in nodes:
for neighbor in node.neighbors:
union(nodeId[node], nodeId[neighbor])
# 将每个set中的node进行存储
components = collections.defaultdict(list)
for node in nodes:
id = find(nodeId[node])
components[id].append(node.label)
# 将components从map中移到list中, 并排序
ret = [sorted(components[i]) for i in components]
ret.sort(key = lambda component : component[0])
return ret ret = sorted([sorted(components[i]) for i in components],
key = lambda component : component[0]) class Solution {
private int[] idxs;
private int[] ranks;
private int count;
private void makeSet(int size) {
idxs = new int[size];
for (int i = 0; i < size; ++i) {
idxs[i] = i;
}
ranks = new int[size];
count = size;
}
private int find(int x) {
while (idxs[x] != x) {
idxs[x] = idxs[idxs[x]];
x = idxs[x];
}
return x;
}
private void union(int x, int y) {
int rootx = find(x);
int rooty = find(y);
if (rootx == rooty) return;
if (ranks[rootx] > ranks[rooty]) idxs[rooty] = x;
else if (ranks[rooty] > ranks[rootx]) idxs[rootx] = y;
else {
idxs[rooty] = x;
ranks[x]++;
}
count--;
}
public int countComponents(int n, int[][] edges) {
if (n < 2) return n;
makeSet(n);
for (int[] edge : edges) {
union(edge[0], edge[1]);
}
return count;
}
}