创建(或打印)数组的排列作为递归和迭代的组合比纯粹迭代更容易完成。肯定有迭代的方法可以做到这一点,但是组合特别简单。具体来说,请注意,根据定义有N!长度 N 数组的排列 - 第一个插槽的 N 个选择,第二个插槽的 N-1 个选项,依此类推。因此,我们可以将算法分解为数组中每个索引 i 的两个步骤。
- 在子数组中选择一个元素作为数组的元素。将该元素与当前位于 的元素交换。
arr[i....end]
ith
arr[i]
- 递归置换 。
arr[i+1...end]
我们注意到这将在O(N!)中运行,因为在第1次调用时将进行N次子调用,每个子调用将进行N-1子调用,依此类推。此外,每个元素最终都会处于每个位置,只要只进行交换,就不会复制任何元素。
public static void permute(int[] arr){
permuteHelper(arr, 0);
}
private static void permuteHelper(int[] arr, int index){
if(index >= arr.length - 1){ //If we are at the last element - nothing left to permute
//System.out.println(Arrays.toString(arr));
//Print the array
System.out.print("[");
for(int i = 0; i < arr.length - 1; i++){
System.out.print(arr[i] + ", ");
}
if(arr.length > 0)
System.out.print(arr[arr.length - 1]);
System.out.println("]");
return;
}
for(int i = index; i < arr.length; i++){ //For each index in the sub array arr[index...end]
//Swap the elements at indices index and i
int t = arr[index];
arr[index] = arr[i];
arr[i] = t;
//Recurse on the sub array arr[index+1...end]
permuteHelper(arr, index+1);
//Swap the elements back
t = arr[index];
arr[index] = arr[i];
arr[i] = t;
}
}
示例输入、输出:
public static void main(String[] args) {
permute(new int[]{1,2,3,4});
}
[1, 2, 3, 4]
[1, 2, 4, 3]
[1, 3, 2, 4]
[1, 3, 4, 2]
[1, 4, 3, 2]
[1, 4, 2, 3]
[2, 1, 3, 4]
[2, 1, 4, 3]
[2, 3, 1, 4]
[2, 3, 4, 1]
[2, 4, 3, 1]
[2, 4, 1, 3]
[3, 2, 1, 4]
[3, 2, 4, 1]
[3, 1, 2, 4]
[3, 1, 4, 2]
[3, 4, 1, 2]
[3, 4, 2, 1]
[4, 2, 3, 1]
[4, 2, 1, 3]
[4, 3, 2, 1]
[4, 3, 1, 2]
[4, 1, 3, 2]
[4, 1, 2, 3]