题目地址:
https://www.lintcode.com/problem/connected-component-in-undirected-graph/description
给定一个无向图,求其所有连通分量,每个连通分量里的数要升序排列。
法1:BFS。注意要先开一个哈希表记录已经访问过的顶点,然后用一个for循环,对图中所有未访问过的顶点一一进行BFS。代码如下:
import java.util.*;
public class Solution {
/*
* @param nodes: a array of Undirected graph node
* @return: a connected set of a Undirected graph
*/
public List<List<Integer>> connectedSet(List<UndirectedGraphNode> nodes) {
// write your code here
List<List<Integer>> res = new ArrayList<>();
if (nodes == null || nodes.isEmpty()) {
return res;
}
Set<UndirectedGraphNode> visited = new HashSet<>();
for (UndirectedGraphNode node : nodes) {
// 如果该node未被访问过,则对其进行BFS并将此连通分量所有点存入一个list并加入res
// 同时标记上这个连通分量里的所有点为已经访问过
if (!visited.contains(node)) {
res.add(bfs(nodes, node, visited));
}
}
return res;
}
private List<Integer> bfs(List<UndirectedGraphNode> nodes, UndirectedGraphNode node, Set<UndirectedGraphNode> visited) {
List<Integer> comp = new ArrayList<>();
comp.add(node.label);
Queue<UndirectedGraphNode> queue = new LinkedList<>();
queue.offer(node);
visited.add(node);
while (!queue.isEmpty()) {
UndirectedGraphNode cur = queue.poll();
for (UndirectedGraphNode neighbor : cur.neighbors) {
if (!visited.contains(neighbor)) {
comp.add(neighbor.label);
queue.offer(neighbor);
visited.add(neighbor);
}
}
}
// 升序排序
Collections.sort(comp);
return comp;
}
}
class UndirectedGraphNode {
int label;
ArrayList<UndirectedGraphNode> neighbors;
UndirectedGraphNode(int x) {
label = x;
neighbors = new ArrayList<>();
}
}
时间复杂度 O ( N + E + ∑ n log n ) O(N+E+\sum n\log n) O(N+E+∑nlogn),后面还需要加上排序的时间。空间 O ( N + E ) O(N+E) O(N+E)。
法2:DFS。思路和BFS是一样的。代码如下:
import java.util.*;
public class Solution2 {
public List<List<Integer>> connectedSet(List<UndirectedGraphNode> nodes) {
// write your code here
List<List<Integer>> res = new ArrayList<>();
if (nodes == null || nodes.isEmpty()) {
return res;
}
Set<UndirectedGraphNode> visited = new HashSet<>();
for (UndirectedGraphNode node : nodes) {
if (!visited.contains(node)) {
List<Integer> comp = new ArrayList<>();
dfs(node, comp, visited);
Collections.sort(comp);
res.add(comp);
}
}
return res;
}
private void dfs(UndirectedGraphNode node, List<Integer> cur, Set<UndirectedGraphNode> visited) {
cur.add(node.label);
visited.add(node);
for (UndirectedGraphNode neighbor : node.neighbors) {
if (!visited.contains(neighbor)) {
dfs(neighbor, cur, visited);
}
}
}
}
时空复杂度不变。