全排列问题为各大公司面试中的热门话题。因为难度适中,技能考察一定的算法思想,又因代码简单,不会耽误很长的时间,因而成为面试官们十分青睐的选择。本文采用分支递归策略解决全排列问题(无重复元素)。掌握好该问题也有助于理解前几篇博客中的回溯法解决排列树的问题(如,批作业调度问题)。
/*
* 该代码运用分治法的思想解决了对于一个任意的集合中元素的全排列问题。(本代码为方便显示用Int型
* 数组代替)。该方法可以传入2个参数,第一个参数为需要全排列的集合,第二个参数为从第几号元素开始
* 进行排列。
* 算法思想:当要开始排列的元素的起始位置已经是最后一个元素时,则无需排列,直接将此时集合输出即可。
* 当要开始排列的元素不是最后一个元素时,则该位置上的元素可以是从当前位置开始之后元素的任意一个。
* 对该位置进行遍历,依次和后面每个元素进行交换,对于交换之后的数组,从其下一个位置开始继续递归调用
* 该方法进行全排列,最终可以得出结果。
* 该全排列的思想对于后面运用回溯法解决排列树类的问题很有帮助。
* 注意:本算法的全排列为完全的全排列。如果要进行去重复元素的全排列,则只需要将该位置元素和后面
* 位置上的不同元素进行交换即可。
* */
package DivideAndConquer;
public class permTest {
static int count = 0;
//需要排列的集合,以及开始排列元素的位置。
public static int Perm(int[] arr,int start){
if(start == arr.length-1){
for(int i=0;i<arr.length;i++)
System.out.print(arr[i]+" ");
System.out.println();
count++;
}
//依次将从该元素开始后面的每个元素放在这个位置,然后从下一个元素开始递归调用本方法。
else{
for(int i=start;i<arr.length;i++){
swap(arr,start,i);
Perm(arr,start+1);
swap(arr,start,i);
}
}
return count;
}
public static void swap(int[] arr,int m,int n){
int temp = arr[m];
arr[m] = arr[n];
arr[n] = temp;
}
public static void main(String[] args){
<span style="white-space:pre"> </span>//对要排列的集合进行初始化。
int n = 5;
int[] list = new int[n];
for(int i=0;i<list.length;i++)
list[i] = i;
int count = Perm(list,0);
System.out.println("共有"+count+"种不同的排列");
}
}