对于N个节点的完整图表,有( N -1)!!独特的完美搭配。如何在 Java 中实现一个方法来枚举所有唯一匹配?
N 的样本输出= 4
[ (0,1), (2,3) ]
[ (0,2), (1,3) ]
[ (0,3), (1,2) ]
N 的样本输出= 6
[ (0,1),(2,3),(4,5) ]
[ (0,1),(2,4),(3,5) ]
[ (0,1),(2,5),(3,4) ]
[ (0,2),(1,3),(4,5) ]
[ (0,2),(1,4),(3,5) ]
[ (0,2),(1,5),(3,4) ]
[ (0,3),(1,2),(4,5) ]
[ (0,3),(1,4),(2,5) ]
[ (0,3),(1,5),(2,4) ]
[ (0,4),(1,2),(3,5) ]
[ (0,4),(1,3),(2,5) ]
[ (0,4),(1,5),(2,3) ]
[ (0,5),(1,2),(3,4) ]
[ (0,5),(1,3),(2,4) ]
[ (0,5),(1,4),(2,3) ]
答案 0 :(得分:1)
我很快就敲了一个Scala程序来做这个,然后转换成Java。所以它不漂亮。
此处使用地图作为对的列表。
/**
*
* @param nodes The nodes still to be added to our edge list.
* @param edges The current edge list. This is mutated, so always return a clone!
*/
public static <N> List<Map<N,N>> enumerateEdges(List<N> nodes,Map<N,N> edges){
if(nodes.isEmpty()) // No more nodes to create edges from, so return our current edge list in a new list.
return Collections.singletonList(new HashMap<>(edges));
N start = nodes.get(0); //The start node of our next pair.
List<Map<N,N>> acc = new LinkedList<>(); //The accumulation of the EdgeLists
for(int i = 1; i<nodes.size(); ++i){
N end = nodes.get(i); //The end node of our pair
edges.put(start,end); //Add this pair to our edge list
List<N> unused = new ArrayList<>(nodes); // The nodes not used in our edge list.
unused.remove(i);
unused.remove(0);
acc.addAll(enumerateEdges(unused,edges));
edges.remove(start); //Remove this pair from our edge list.
}
return acc;
}
可以使用 accumulators / tail recursion / lazyness 完成更多工作以提高性能。但这很有效。
用以下方式调用:
List<Map<Integer,Integer>> results = enumerateEdges(Arrays.asList(0,1,2,3),new HashMap<>());