1.递归实现全排列去重算法
设全排列的元素集合为S={r1,r2,r3……},Sn表示全部n个元素进行全排列的个数,则递推式为Sn=r1S(n-1)+r2S(n-2)+…+rnS(n-1);
riS(n-1)的意思是以ri开头,剩下n-1个元素进行全排列的个数,显然S1=r1=1。
那么每次怎么得到以不同元素开头的S(n-1)呢,通过交换swap(当前第一个元素,后面的各个元素)。
去重:将第一个元素与跟它不相等的元素交换
代码:
public class FullArrange1 {
public static int count = 0; // 全排列个数
public static void allRange(int[] a, int k, int m) {
// k==m意味着得到一个全排列
if (k == m) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
count++;
} else {
// 让第k个位置的元素依次与k,k+1...m位置的元素交换
for (int i = k; i <= m; i++) {
if(a[i]!=a[k]
swap(a, i, k);
FullArrange(a, k + 1, m); //递归
if(a[i]!=a[k]
swap(a, i, k); // 复原之前的序列
}
}
}
public static void swap(int[] a, int i, int k) {
int temp = a[i];
a[i] = a[k];
a[k] = temp;
}
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4 ,5,6,7,8,9};
FullArrange(a, 0, a.length - 1);
System.out.println("总共有" + count + "个排列");
}
}
//这个方法是转载的
public class FullArrange2{
public static int arr[] = new int[]{0,0,0};
public static void main(String[] args) {
perm(3);
}
/**
* 数组变化过程:
* 3 0 0
* 3 2 0
* 3 2 1
* 3 2 0
* 3 0 0
* 3 0 2
* 3 1 2
* 3 0 2
* 3 0 0
* 0 0 0
* 0 3 0
* 2 3 0
* 2 3 1
* 2 3 0
* 0 3 0
* 0 3 2
* 1 3 2
* 0 3 2
* 0 3 0
* 0 0 0
* 0 0 3
* 2 0 3
* 2 1 3
* 2 0 3
* 0 0 3
* 0 2 3
* 1 2 3
* 0 2 3
* 0 0 3
* 0 0 0
* @param m
*/
private static void perm(int m) {
if(m==0){
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
return;
}
else{
for(int i=0;i<arr.length;i++){
if(arr[i]==0){
arr[i] = m;
perm(m-1);
arr[i] = 0;
}
}
}
}
}