再帰的な方法を使用します。これは、必要なすべてのサブセットを正確に生成するため、最適な実行時間であると思います。
public static void solve(int[] a, int k, int i, List<List<Integer>> subsets) {
if (i == a.length) {
for (List<Integer> subset : subsets) {
System.out.print(subset);
}
System.out.println();
} else {
// loop over all subsets and try to put a[i] in
for (int j = 0; j < subsets.size(); j++) {
if (subsets.get(j).size() < k) {
// subset j not full
subsets.get(j).add(a[i]);
solve(a, k, i+1, subsets); // do recursion
subsets.get(j).remove((Integer)a[i]);
if (subsets.get(j).size() == 0) {
// don't skip empty subsets, so you won't get duplicates
break;
}
}
}
}
}
使用法:
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5, 6};
int k = 3;
List<List<Integer>> subsets = new ArrayList<List<Integer>>(a.length / k);
for (int i = 0; i < a.length / k; i++)
subsets.add(new ArrayList<Integer>(k));
solve(a, k, 0, subsets);
}
プリント:
[1, 2, 3][4, 5, 6]
[1, 2, 4][3, 5, 6]
[1, 2, 5][3, 4, 6]
[1, 2, 6][3, 4, 5]
[1, 3, 4][2, 5, 6]
[1, 3, 5][2, 4, 6]
[1, 3, 6][2, 4, 5]
[1, 4, 5][2, 3, 6]
[1, 4, 6][2, 3, 5]
[1, 5, 6][2, 3, 4]