Java 整数数组的置换算法
有一个集合,例如(1,4,2,5,7,6,9,8,3)。我们用以下方法计算它的Java 整数数组的置换算法,java,algorithm,permutation,Java,Algorithm,Permutation,有一个集合,例如(1,4,2,5,7,6,9,8,3)。我们用以下方法计算它的第一个差分(FD):第一个差分[i]=inputArray[i+1]-inputArray[i]。输入阵列是原始设置。在示例中,情况是(1、4、2、5、7、6、9、8、3)。第一个差异是通过以下方式从inputArray创建的:(inputArray的第二个元素)-(inputArray的第一个元素)依此类推 所以给定集合的FD是(3,-2,3,2,-1,3,-1,-5)。任务是找到给定集合的若干置换,其中第一个差分是
第一个差分
(FD):第一个差分[i]=inputArray[i+1]-inputArray[i]
。输入阵列是原始设置。在示例中,情况是(1、4、2、5、7、6、9、8、3)。第一个差异是通过以下方式从inputArray创建的:(inputArray的第二个元素)-(inputArray的第一个元素)依此类推
所以给定集合的FD是(3,-2,3,2,-1,3,-1,-5)。任务是找到给定集合的若干置换,其中第一个差分是FD的置换。在这个例子中,我们应该找到(1,4,2,5,7,6,9,8,3)的排列,第一个不同点是(3,-2,3,2,-1,3,-1,-5)的排列
这是我的算法:
但是这个算法太慢了。你能帮助创建更快的算法吗?也许我做了一些可以消除的步骤 这是个大问题。。。如果我理解的没错,你需要找到原始集合的所有置换,它们保持了原始FD集合的置换 你的算法可以工作,除了你通过查看原始集合的所有排列,然后是那些FD的所有排列,来计算许多不必要的排列。如果您首先查看原始FD的所有可能排列,您应该能够消除原始集合的一组排列 换句话说:
在计算该示例时,当您进入步骤3时,您应该能够自动消除以1、5开头的任何排列,因为4的差永远不会出现在原始FD的任何排列中。在这个特定的例子中,它只会为您节省一些计算,但是一旦您开始使用更大的集合,这个算法就有可能为您节省大量的时间。您不需要计算置换。首先要注意的是,在您的示例中,差分数组中有17个从-8到8的可能值,但实际数组中只有五个不同的值 制作一个矩阵并划掉所有未出现的值(括号中): 如果原始数组中的当前项为1,则下一项必须为4或3,否则将无法获得差分数组的排列。您可以将此信息存储在图形中:
1 -> 4, 3
2 -> 1, 4, 5
3 -> 1, 2, 5, 6
4 -> 2, 7, 6, 3
5 -> 4, 7, 8, 3
6 -> 1, 4, 5, 9, 8
7 -> 2, 5, 6, 9
8 -> 7, 6, 3
9 -> 4, 7, 8
现在,将目标差异数组转换为一个映射,在该映射中存储元素在数组中出现的频率:
count[-5]: 1
count[-2]: 1
count[-1]: 2
count[2]: 1
count[3]: 3
然后可以在图形中查找原始数组长度的路径。您必须跟踪是否已访问某个节点。您还应该通过递减“count”来跟踪已经使用的差异。如果找到了所需长度的路径,则具有有效的排列
在伪代码中:
map count;
set visited;
function walk(a, left, path) {
left--;
if (left == 0) {
print path;
return;
}
a.visited = true;
foreach (b in graph[a]) {
d = b - a;
if (count[d] > 0 && b.visited == false) {
count[d]--;
walk(b, left, path + [b]);
count[d]++;
}
a.visited = false;
}
foreach (a in A) {
walk(a, A.length, [a]);
}
任务是找到给定集合的若干排列,其中第一个不同点是FD的排列。
您能详细说明一下吗?此外,如果你格式化你的问题,它会更可读。与您现在的文本块相比,请详细说明FD的排列。您所说的FD的排列是什么意思?我不明白的一件事是如何找到可以消除的集合。我应该如何处理原始集合以找到永远不会出现在FD中的数字?您打算如何找到给定集合的所有置换?基本上,您只需采用相同的逻辑,并在排列中的下一个数字产生FD中没有的差异时添加停止功能。这种a-la DFS方法肯定比原始暴力尝试和公认答案(阶乘(!)复杂性)更快。我不确定给定解决方案的确切复杂度是多少,但感觉仍然可以优化,例如任何解决方案集中最后一个和第一个元素之间的距离(或路径
始终与原始设置中的最后一个
-第一个
相同。无论如何,+1我同意最后一张海报…这绝对是一个比我原始答案更好的解决方案。我喜欢从条目之间的差异来解决问题,而不是从单个排列来解决问题。这将定义它ely的构建开销要大得多,但与我的算法相比,它的运行速度会非常快。干得好!+1
map count;
set visited;
function walk(a, left, path) {
left--;
if (left == 0) {
print path;
return;
}
a.visited = true;
foreach (b in graph[a]) {
d = b - a;
if (count[d] > 0 && b.visited == false) {
count[d]--;
walk(b, left, path + [b]);
count[d]++;
}
a.visited = false;
}
foreach (a in A) {
walk(a, A.length, [a]);
}