排列组合那些事

来源:互联网 发布:淘宝网店装修模板代码 编辑:程序博客网 时间:2024/06/10 04:37
          排列问题   
 类型一:固定序列,1,2,3,...,n全排列
/* *  *   从1...n之中进行全排列,传入n,默认数据:[1,2,...,n] *    * */public class allArrange {    //数组的个数private int n;//数组中每个数是否被访问过的标记private int []x;//结果数组private int []result;//记录全排列种数。private int sum;public allArrange(int n){ this.n=n;     sum=0;     x=new int [n];     result=new int [n];          for(int i=0;i<n;i++)     x[i]=0;                backtrack(0);     System.out.println("总共有 "+sum+" 种全排列方式");      }private void backtrack(int t){//递归出口:到第n层,打印结果。 if(t>n-1) { print();return;}  else{ //采用循环递归的方式  (回溯法) for(int i=0;i<n;i++){ //没有被访问过,标记,记录该数,进入下一层if(bound(i)){     x[i]=1;     result[t]=i+1; backtrack(t+1);     x[i]=0; } }}}//被访问过,则返回falseprivate boolean bound(int t){ if(x[t]==1)return false; return true;} //打印输出    public void print(){sum++;for(int i=0;i<n;i++)System.out.print(result[i]+" ");System.out.print("\n");}}

类型二: 含重复数的全排列

public class generalAllArrange {private int n;private int []x;private int []result;private int sum;    public generalAllArrange(int []a){    this.n=a.length;    x=a;    result=new int[n];        /*显示更直观一点,利用快排排个序*/     //sort(0,n-1);     backtrack(0);        System.out.println("总共有 "+sum+" 种全排列方式");    }    void swap(int [] arr,int m,int n){        int temp=arr[m];        arr[m]=arr[n];        arr[n]=temp;   }/* * 快排函数 * */private void sort(int l,int r) {// TODO Auto-generated method stubif(l<r){int q=position(l,r);sort(l,q-1);sort(q+1,r);}}private int position(int l,int r){int i=l,j=r+1;int a=x[l]; while(true){ while(x[++i]<a&&i<r); while(x[--j]>a); if(i>=j)break; swap(x,i,j); } x[l]=x[j]; x[j]=a;return j;}/* * 回溯 * */private void backtrack(int t){ if(t>n-1) { print();return;}  else{ for(int i=t;i<n;i++){ if(bound(i)){     swap(x,i,t); backtrack(t+1); swap(x,i,t); } }}}//当后面的数和该层的数相同,则不需要交换private boolean bound(int t){for(int i=t+1;i<n;i++) if(x[t]==x[i])return false; return true;}    public void print(){sum++;for(int i=0;i<n;i++)System.out.print(x[i]+" ");System.out.print("\n");}}

组合问题

类型一:

固定序列,1,2,3,...,n的K组合

/* * 已知非负整数n,k,列出集合S属于{1,2,...,n}的所有k组合 * */public class kArrange {   //数组个数private int n;       //选取个数 private int k; //数组中每个数是否被访问过的标记private int []x;//结果数组private int []result;//记录K组合种数。private int sum;public kArrange(int n,int k){ this.n=n; this.k=k;     sum=0;        x=new int [n];     result=new int [k];          for(int i=0;i<n;i++)     x[i]=0;          backtrack(0);     System.out.println("总共有 "+sum+" 种K组合方式");      }private void backtrack(int t){ if(t>k-1) { print();return;}  else{ for(int i=t;i<n;i++){ if(bound(i)&&constraint(t,i)){     x[i]=1; result[t]=i+1; backtrack(t+1);     x[i]=0; } }}}//被访问过,则返回falseprivate boolean bound(int t){ if(x[t]==1)return false; return true;} //从大到小的顺序, 去重。private boolean constraint(int t,int i) {     if(t>0&&(result[t-1]>i+1)) return false; return true;}    public void print(){sum++;for(int i=0;i<k;i++)System.out.print(result[i]+" ");System.out.print("\n");}}


类型二:含重复数的K组合问题

(不会,以后再来写。)


java完整链接:链接:https://pan.baidu.com/s/1o8IFJHg 密码:7md7




原创粉丝点击