【发布时间】:2023-03-17 17:41:01
【问题描述】:
我有一个由 32 个数字组成的数组 [1,2,3,4,4,4,4,5,5,5,5,5,6,6,7,7,7,7,8,9 ,10,10,11,12,13,13,14,14,15,16,17,17]
我想将此数组划分为 8 个子数组,每个子数组的大小为 4,这样子数组就不会有重复的元素。
我有多少种方法可以做到这一点?生成所有排列和单个随机排列的最佳解决方案是什么。子数组的顺序无关紧要。每个子数组中的元素顺序也没有。
对于我最初的问题,我不需要生成所有排列。每次运行我的程序时,我只需要生成一个随机排列。
我的方法是使用 Fisher-Yates 算法随机打乱数组并不断重新打乱它,直到我得到所有 8 个没有重复元素的子数组。当然这不是最好的方法。
作为我的解决方案的一部分,我对数组进行了混洗,并从这个混洗后的数组开始将元素一一添加到子数组中。如果任何子数组已经有一个数字,那么我会继续从我的洗牌数组中跳过元素,直到我到达一个不是我的子数组的数字。这种方法在某些情况下会失败。
我尝试过的伪代码
let shuffledArray = shuffle(originalArray);
let subArrays = [];
for (let i = 0; i < 8; i++) {
subArrays[i] = [];
for (let j = 0; j < 32; j++) {
if (!subArrays[i].contains(shuffledArray[j]) && !shuffledArray[j].used) {
subArrays[i].push(shuffledArray[j])
shuffledArray[j].used = true;
}
if (subArrays[i].length == 4) {
break;
}
}
}
if subArrays has any sub array such that it has duplicate elements then repeat above steps
else we have generated a random permutation
如您所见,上述方法在将所有重复的数字放在最后时失败,因此我一次又一次地重复所有步骤,直到得到结果。
我正在使用 JavaScript,但欢迎使用任何语言的答案,只要它们可以转换为 JavaScript。
如果有人能提供 N 个元素和 K 个组的通用解决方案,那就太好了。
这是我在 SO 的第一个问题。随意编辑/提出改进建议。
【问题讨论】:
-
@MarkMeyer 这是
[1,2,3,4][4,5,6,7][4,5,6,7][4,5,7,8][5,7,9,10][5,10,11,12][13,14,15,17][13,14,16,17]和[1,2,13,14][4,5,16,17][4,5,6,7][4,5,7,8][5,7,9,10][5,10,11,12][13,14,15,17][3,4,6,7]和[17,2,13,4][4,5,6,7][4,5,6,7][4,5,7,8][5,7,9,10][5,10,11,12][13,14,15,17][3,14,16,1]的三种可能组合
标签: arrays algorithm permutation combinatorics