理论:
將一組數字、字母或符號進行排列,以得到不同的組合順序,例如1 2 3這三個數的排列組合有:1 2 3、1 3 2、2 1 3、2 3 1、3 1 2、3 2 1。
解法:
可以使用递迴将问题切割為较小的单元进行排列组合,例如1 2 3 4的排列可以分為1 [2 3 4]、2 [1 3 4]、3 [1 2 4]、4 [1 2 3]进行排列,这边利用旋转法,先将旋转间隔设為0,将最右边的数字旋转至最左边,并逐步增加旋转的间隔,例如:
1 2 3 4 -> 旋转1 -> 继续将右边2 3 4进行递迴处理
2 1 3 4 -> 旋转1 2 变為 2 1-> 继续将右边1 3 4进行递迴处理
3 1 2 4 -> 旋转1 2 3变為 3 1 2 -> 继续将右边1 2 4进行递迴处理
4 1 2 3 -> 旋转1 2 3 4变為4 1 2 3 -> 继续将右边1 2 3进行递迴处理
java实现:
package 经典; public class Permutation { public static final int N=4; /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int[] arr=new int[N+1]; for(int i=1; i<=N; i++) arr[i]=i; perm(arr,1); } public static void perm(int[] a,int i){ if(i<a.length-1) { for(int j=i; j<=a.length-1; j++) { int tmp=a[j]; for(int k=j; k>i; k--) a[k]=a[k-1]; a[i]=tmp; perm(a,i+1); for(int k=i; k<j; k++) a[k]=a[k+1]; a[j]=tmp; } } else { // 顯示此次排列 for(int j = 1; j <= a.length - 1; j++) System.out.print(a[j] + " "); System.out.println(); } } }
package 经典; import java.lang.reflect.Array; import java.util.Arrays; import java.util.LinkedList; import java.util.List; public class 数组组合1 { public 数组组合1() { // TODO 自动生成的构造函数存根 } public static void listAll(List candidate,String prefix){ if(candidate.isEmpty()) System.out.println(prefix); for(int i=0 ;i<candidate.size(); i++) { List temp=new LinkedList(candidate); listAll(temp,prefix+temp.remove(i)); } } /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 String[] array=new String[]{ "1","2","3","4","5" }; listAll(Arrays.asList(array),""); } }