给定N个数(N是偶数),给它们进行两两组合并列举所有可能的轮数,每一轮的组合不可以一样,并且两个元素只允许组合一次。
比如N是4,有A,B,C,D共4个元素,那么可以共有3轮组合,分别是:
第一轮 | 第二轮 | 第三轮 |
---|---|---|
A-B,C-D | A-C,B-D | A-D,B-C |
从第四轮开始要开始重复了,因此这里不重复组合的最大轮数是3
输入是一个含有偶数元素的列表,输出是排好之后的每一轮。
首先要明确组合的规律,也可以说是条件:
可以使用回溯法来解决问题,思路是:
以上是分析思路,如果写程序的话,步骤2-6要倒着写,因为大的条件判断要放在前面。
具体的代码可以参考https://github.com/ILoveStudyAndWork/pair-generator
上述的过程在PairGenerator的generatePairSchedule()里面,要跑的话可以在Solution中运行,运行的步骤可以参考打印在控制台的结果,会显示每次选择后各个列表的元素。
可以扩展成一个现实问题,团队有N个人,每次工作需要两两组合完成任务,如果是人数是单数那么有一个人会单独做。这个程序就可以生成组合的计划,让每个人都和其他人互相组合。
运行时只需要把成员的名单放到teamMembers中
Set<String> teamMembers = new HashSet<>(); teamMembers.add("A"); teamMembers.add("B"); teamMembers.add("C"); teamMembers.add("D"); teamMembers.add("E"); PairGenerator pairGenerator = new PairGenerator(teamMembers); pairGenerator.generatePairSchedule(); pairGenerator.printSolution();
而且这个程序支持输入成员,如果是单数成员,程序会自动补全一位(Nobody)变成偶数
选择的过程可以参考打印出来的log,例如选择了第一个元素A + B之后,各列表的元素是:
selectedPairs pairs:
A + B
disable pairs:
0:
A + C
A + D
A + E
A + Nobody
B + C
B + D
B + E
B + Nobody
Choosable pairs:
C + D
C + E
C + Nobody
D + E
D + Nobody
E + Nobody
result:
例如选择了第二个元素C + D之后,各列表的元素是:
selectedPairs pairs:
A + B
C + D
disable pairs:
0:
A + C
A + D
A + E
A + Nobody
B + C
B + D
B + E
B + Nobody
1:
C + E
C + Nobody
D + E
D + Nobody
Choosable pairs:
E + Nobody
result: