1、无重复元素的全排列
public class 无重复全排列{
static int [] a= {1,2,3,4,5,6,7,8,9};
static int ans;
/*
* 递归回溯生成全排列,适用于无重复元素
* 全排列,考虑第k位,前面已经排定
*/
static void f(int k) {
if(k==9) { //其中一种排列已经产生
int x1=a[0]+a[1]+a[3]+a[5];
int x2=a[0]+a[2]+a[4]+a[8];
int x3=a[5]+a[6]+a[7]+a[8];
if(x1==x2 && x2==x3) {
ans++;
}
}
//从K往后的每个数字都可以放在第K位
for(int i=k;i<9;i++) {
//交换
int t=a[k];a[k]=a[i];a[i]=t;
f(k+1); //递归,去考虑第K+1位
//回溯
t=a[k];a[k]=a[i];a[i]=t;
}
}
/*
* A,2,3,4,5,6,7,8,9共九张纸牌排成一个三角形(A按1计算),要求每个边相等
* 下面是一种排法
* A
* 9 6
* 4 8
* 3 7 5 2
* 这样的排法可能会有分多种,如果考虑没有旋转,镜像后相同的一种,一共有多少不同的排法?
*/
public static void main(String[] args) {
// TODO 自动生成的方法存根
f(0);
System.out.print(ans/6);
}
}
2、重复元素的全排列
public class 重复全排列{
static int a[]={0,0,0,0,0,0,0,1,1,1,1,1};
static int ans;
static boolean book[]=new boolean[12];
static void f(int k,int path []){
if(k==12){
if(check(path)){
ans++;
}
}
for(int i=0;i<12;i++){
//现在准备选取的元素和上一个相同的元素,但上一个元素还没有抓取
if(i>0 && a[i]==a[i-1] && !book[i-1]) continue;
//没有被用过的元素可以抓入到path
if(!book[i]){
book[i]=true;//标记已访问
path[k]=a[i];//将a[i]填入path[k]中
f(k+1,path) //递归
book[i]=false;//回溯
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
int path []=new int [12];
f(0,path);
}
}
注意:以上代码仅供参考,主要部分已经展出,运行结果不一定正确,切勿纠结。