在尝试使用递归进行排列问题时,我在Internet上看到了这个解决方案,但我不确定这是如何产生数组的每个可能的排列。
非常感谢明确,简洁的解释
public static void permute(int [] list, int index){
if(index == list.length){
System.out.println(Arrays.toString(list));
}
else{
for(int i = index; i < list.length; i++){
swap(list, index, i);
knapsack(list, index + 1);
swap(list, index, i);
}
}
}
public static void swap (int [] a, int b, int c){
int temp = a[b];
a[b] = a[c];
a[c] = temp;
}
答案 0 :(得分:0)
我假设您的示例代码中knapsack
应该是permute
。此外,还有一个重要的部分缺失:必须有代码才能启动整个过程,例如
public static void printAllPermutations(int[] list) {
permute(list, 0);
}
递归的本质是你通过解决相同问题的较小实例来解决问题,而那些较小的解决方案解决了更小的实例,依此类推,直到你得到一个&#34;基本情况&# 34 ;.假设使用此列表调用printAllPermutations
:
[1, 2, 3, 4, 5]
这会调用permute(list,0)
。循环中的逻辑使用swap
将每个元素放入第一个元素,然后将它们交换回来;结果是它将与这些列表中的每一个一起使用:
[1, 2, 3, 4, 5]
[2, 1, 3, 4, 5]
[3, 2, 1, 4, 5]
[4, 2, 3, 1, 5]
[5, 2, 3, 4, 1]
递归调用使代码找到最后四个元素的所有排列。因此,当您使用[1, 2, 3, 4, 5]
时,permute
方法会计算[2, 3, 4, 5]
的所有排列(同一问题的较小实例)。这意味着对于[2, 3, 4, 5]
的每个排列,该方法将输出该排列,前面有1。类似地,对于[1, 3, 4, 5]
的所有排列,它将输出每个排列,前面有2,依此类推。如果您可以相信该方法适用于这四个元素,那么您可以看到它适用于五个元素。如果你可以相信它适用于三个元素,那么你可以相信它适用于四个元素,依此类推。当它归结为零元素时,没有什么可做的,因为只有一个排列。 (实际上,当它归结为一个元素时,没有任何事可做,这意味着第一个if
可能是if (index >= list.length-1)
。)这是&#34;基础情况下&#34 ;.由于只有一个排列,并且它根本不涉及更改列表,因此唯一要做的就是打印它。