给定一个大小为2n的列表,如何找到所有可能的n对而不重复?该算法最好是最优的,因为在我的情况下n很大。
例如,给出一个列表
[1, 2, 3, 4],
字符串
它应该返回
[[1, 2], [3, 4]]
[[1, 3], [2, 4]]
[[1, 4], [2, 3]]
型
一般来说,它应该返回(2n,2)* (2n-2,2) *... *(2,2)2D列表,其中(n,m)是在n个项目中挑选m个项目的组合数。
我使用的是Python 3。我尝试了Python itertools.combinations,通过3个步骤以蛮力的方式解决了这个问题:
1.求所有有序对[i,j],i<j,例如在上面的例子中,我们有[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]。
1.使用itertools.combinations将上述对合并组合成n对,例如它有[[1,2],[1,3]]等
1.在步骤2中,通过将它们展平为1D,然后使用Python set,然后比较长度来删除重复的对,即[[1,2],[1,3]]是坏的,因为1是重复的。这个列表对应的集合是{1,2,3},其长度为3但不是4。因此,它被删除。
**我的目标是加速算法,而不是使用上面的蛮力方法,因为在我的情况下n很大。
1条答案
按热度按时间jgzswidk1#
首先,你对组合数的计算是错误的,正如你的简单例子所示。choose(4,2)* choose(2,2)= 6 * 1 = 6,然而,正如你所看到的,只有三种可能性。您不希望算法同时产生
[[1, 2], [3, 4]]
和[[3, 4], [1, 2]
,但认为它们是相同的结果。您需要进行计算并除以在n!也就是说,看看所有的结果,就像你上面看到的那样,
字符串
规范表示是其中
x1 < x2 < x3 < ....
,x1 < y1
,x2 < y2
,x3 < y3
,.由此,很容易看出
x1
必须是1,x2
必须是去除x1
和y1
后的所有元素中最小的,x3
必须是去除x1
、x2
、y1
和y2
后的所有元素中最小的。这给了你一个很好的递归算法:
型