我有一个HashMap:
Key,Value
A,C
B,C
C,D
E,F
这是邻接名单。带有两个分区的图形,其中第一个分区包含节点{A,B,C,D},第二个分区是{E,F}。
问题:给定代表邻接列表的HashMap返回分区。
换句话说:
Input: {[A,C],[B,C],[C,D],[E,F]}
Output: {[A,B,C,D],[E,F]}
用Java解决这个问题的一些解决方案/算法???
Ps:不限于Java,欢迎任何帮助:)
事先提前:)
答案 0 :(得分:0)
您可以使用任何图形遍历技术(BFS或DFS)。
例如,如果您使用的是BFS:
从任何节点开始(比方说X)。
访问连接到此节点的所有节点后,检查是否访问了图的所有节点。如果遇到未访问的节点,请从此节点启动一个新的BFS,这将是您的第二个分区。
在您的情况下,如果您从A启动BFS,它将访问[C,B,D]。这是第一个分区。
现在检查图表(E)中是否有未访问的节点。所以,现在你从E开始一个BFS,你访问的所有节点都在第二个分区。
答案 1 :(得分:0)
IMO最佳解决方案是Union-Find algorithm
public class UnionFind {
Map<String, String> parents = new HashMap<>();
Map<String, Integer> representantElements = new HashMap<>();
public void union(String p0, String p1) {
String cp0 = find(p0);
String cp1 = find(p1);
if (!cp0.equals(cp1)) {
int size0 = representantElements.get(cp0);
int size1 = representantElements.get(cp1);
if (size1 < size0) {
String swap = cp0;
cp0 = cp1;
cp1 = swap;
}
representantElements.put(cp0, size0 + size1);
parents.put(cp1, cp0);
representantElements.put(cp1, 0);
}
}
public String find(String p) {
if (!representantElements.containsKey(p)){
representantElements.put(p, 1);
return p;
}
String result = parents.get(p);
if (result == null) {
result = p;
} else {
result = find(result);
parents.put(p, result);
}
return result;
}
public Set<Set<String>> getPartitions() {
Map<String, Set<String>> result = new HashMap<>();
representantElements.forEach((key, value) -> {if (value > 0) {result.put(key, new HashSet<>(value));};});
representantElements.forEach((key, value) -> result.get(find(key)).add(key));
return new HashSet<>(result.values());
}
public static Set<Set<String>> partitions(String[][] pairs) {
UnionFind groups = new UnionFind();
for (String[] pair : pairs) {
if (pair.length > 1) {
String first = pair[0];
for (int i = 1; i < pair.length; i++) {
groups.union(first, pair[i]);
}
}
}
return groups.getPartitions();
}
public static void main(String[] args) {
String[][] elements = {{"A","C"},{"B","C"},{"C","D"},{"E","F"}};
for (Set<String> partition : partitions(elements)) {
System.out.println(partition);
}
}
}
打印:
[A, B, C, D]
[E, F]