全排列递归求解
1 public class Main { 2 3 //思路:对每一个子递归的数组(除去第一个数的数组)进行全排列,并用除去的第一个数对所有子数组的全排列的每一项进行交换 4 5 public static void swap(int[] a,int cursor,int i) { 6 int temp=a[cursor]; 7 a[cursor]=a[i]; 8 a[i]=temp; 9 } 10 11 public static void digui(int[] a,int cursor,int end) { 12 if(cursor==end) { 13 for(int i=0;i<5;i++) { 14 System.out.print(a[i]); 15 } 16 System.out.println(); 17 } 18 else { 19 for(int i=cursor;i<=end;i++) { 20 swap(a,cursor,i); 21 digui(a,cursor+1,end); 22 swap(a,cursor,i); 23 } 24 } 25 } 26 27 public static void main(String[] args) { 28 int[] a = {1,2,3,4,5}; 29 digui(a,0,4); 30 } 31 32 }
全排列有重复元素情况时
public class Main { // 思路:有重复时加入方法,进行交换时若要交换的中间若有相同的数字,则停止本次交换意图 //例如12335,先进行的第2个3和5的交换没有在中间发现3,则成功进行12353.在第一个3和5发生交换时发现了中间的3,则取消本次交换。 //12533为在12353状态下第一个3和5进行的交换 public static boolean swapaccepted(int[] array,int start,int end) { for(int i=start;i<end;i++) { if(array[i]==array[end]) { return false; } } return true; } public static void swap(int[] a, int cursor, int i) { if (a[cursor] != a[i]) { int temp = a[cursor]; a[cursor] = a[i]; a[i] = temp; } } public static void digui(int[] a, int cursor, int end) { if (cursor == end) { for (int i = 0; i < 5; i++) { System.out.print(a[i]); } System.out.println(); } else { for (int i = cursor; i <= end; i++) { if(!swapaccepted(a,cursor,i)) { continue; } swap(a, cursor, i); digui(a, cursor + 1, end); swap(a, cursor, i); } } } public static void main(String[] args) { int[] a = { 1, 2, 3, 3, 5 }; digui(a, 0, 4); } }
组合有几种取法
1 //组合,m个球取出n个有几种取法 2 //递归计数两部走:1.取到了某一个球,则再从剩下的m-1个里取n-1个 (隐含第二步)2.永远都没取到这个球,从剩下的m-1个里选n个 3 public class Main { 4 5 public static int digui(int m, int n) { 6 if (n == m) 7 return 1; 8 if (n == 0) 9 return 1; 10 else 11 return digui(m - 1, n - 1) + digui(m - 1, n); 12 } 13 14 public static void main(String[] args) { 15 System.out.println(digui(5, 3)); 16 } 17 18 }
组合无重复需要列出所有情况
1 //组合,列出m个球取出n个所有组合 2 //组合类似于多for循环,在第一个数为什么的情况下找第二个数,在前两个数既定的情况下找下一个,注意回溯 3 public class Main { 4 5 public static void digui(int[] a, int cursor, int remain, String s,int num) { 6 7 if (remain == 0) 8 System.out.println(s); 9 10 else { 11 for (int i = cursor; i <= a.length-1; i++) { 12 s += Integer.toString(a[i]); 13 digui(a, i + 1, remain-1, s,num); 14 s=s.substring(0, num-remain); 15 } 16 } 17 18 } 19 20 public static void main(String[] args) { 21 int[] a = { 1, 2, 3, 4, 5 }; 22 digui(a, 0, 3, "",3); 23 } 24 25 }
组合有重复情况列出所有
1 //组合,列出m个球取出n个所有组合且球里有重复的 2 //类似于无重复组合思路,将问题数组改为表示元素个数的数组,并在递归是进行判断是否超过了球的个数。类似于多循环间加入限定条件if 3 public class Main { 4 5 public static void digui(int[] b, int cursor, int remain, int[] c, int num) { 6 7 if (remain == 0) { 8 for (int i = 0; i < c.length; i++) 9 System.out.print(c[i]);//为了好理解只输出个数数组 10 System.out.println(); 11 } else { 12 for (int i = cursor; i<b.length; i++) { 13 c[i]++; 14 if (c[i] >= b[i]) 15 digui(b, i + 1, remain - 1, c, num); 16 else 17 digui(b, i, remain - 1, c, num); 18 c[i]--; 19 } 20 } 21 22 } 23 24 public static void main(String[] args) { 25 int[] a = { 1, 1, 2, 2, 2, 3 }; 26 int[] b = { 2, 3, 1 };// 将原数组改写为个数数组 27 int[] c = new int[3]; 28 digui(b, 0, 3, c, 3); 29 } 30 31 }