package month7.dp; import java.util.Arrays; public class 全排列 { public static void main(String[] args) { 全排列 a = new 全排列(); int[] arr = { 1, 2, 2 }; a.perm(arr, 0, arr.length - 1); System.out.println("=============="); a.perm_removeSame(arr, 0, arr.length-1); } /** * 將數組中的元素,從下標 start 到 end 做全排列(未考慮重復的元素) * @param arr 要排列的數組 * @param start 起始的位置 * @param end 終止的位置 */ public void perm(int[] arr, int start, int end) { if (start == end) { System.out.println(Arrays.toString(arr)); } for (int i = start; i <= end; i++) { swap(arr, start, i); // 第一個數,從0開始,依次與后面的數相交換 perm(arr, start + 1, end); swap(arr, i, start); } } private void swap(int[] arr, int start, int i) { int tmp = arr[start]; arr[start] = arr[i]; arr[i] = tmp; } // 那當字符串中出現重復的字符時,如何生成不重復的排列? // ---去重的全排列就是從第一個數字起每個數分別與它后面非重復出現的數字交換 public void perm_removeSame(int[] arr, int start, int end) { if (start == end) { System.out.println(Arrays.toString(arr)); } for (int i = start; i <= end; i++) { // 只有當沒有重疊的字符 才交換 if(!isSwap(arr, start, i)) { swap(arr, start, i); perm_removeSame(arr, start+1, end); swap(arr, i, start); } } } //[start,end) 中是否有與 arr[end] 相同的字符 private boolean isSwap(int[] arr, int start, int end) { for(int i=start;i<end;i++){ if(arr[i] == arr[end]){ return true; } } return false; } }