问题:对序列进行全排列,例如 1 2 3的全排列有1 2 3 ,1 3 2,2 1 3,...共6种不同的排序方式,n个元素的数组的排序结果有n!个不同排序结果.实现该功能
import java.util.ArrayList; import java.util.Arrays; /* * 本方法使用递归调用的方式,复杂度为n!,有待优化 */ public class Main { public static void main(String[] args) { //构造一个数组,实现它的全排列 String[] srcArr = { "a", "b", "c", "d" }; //result即上面数组的全排列结果,以数组列表形式存储有n!个元素,每个元素为一个排列顺序的数组 ArrayList<String[]> result = testArrange(srcArr); //打印结果, while (!result.isEmpty()) { System.out.println(Arrays.toString(result.get(0))); result.remove(0); } } /* * 全排列递归方法,n个元素的数组,分别将每个元素放置在第一位,剩下的顺序不变构造能n-1个元素的数组,递归调用本方法 * 直至只有2个元素,交换顺序,返回 */ public static ArrayList<String[]> testArrange(String[] srcArr) { ArrayList<String[]> result = new ArrayList<>(); int length = srcArr.length; //如果只有两个元素,那么只有两个排列,原顺序和交换后的顺序 if (length == 2) { result.add(srcArr); result.add(exchangeElement(srcArr, 0, 1)); } else { //从第一个元素到最后一个元素,依次取出,放置在第一个位置, // 其他元素按照原来的顺序递归调用本方法,直至只有两个元素 for (int i = 0; i < length; i++) { String[] before = new String[1]; // befor用于存储第一个元素, before[0] = srcArr[i]; String[] tmp = new String[length - 1]; // tmp是原数组取出第i个元素放置在第一个位置后的剩下的数组 tmp = reduceArr(srcArr, i); //对剩下的部分递归,实现全排列 ArrayList<String[]> afterList = testArrange(tmp); while (!afterList.isEmpty()) { // 将第一个元素和剩下部分的全排列后的进行拼接 result.add(appendArr(before, afterList.get(0))); afterList.remove(0); } } } return result; } /* * 交换数组中i,和j两个元素的值 */ public static String[] exchangeElement(String[] srcArr, int i, int j) { String[] result = Arrays.copyOf(srcArr, srcArr.length); result[i] = srcArr[j]; result[j] = srcArr[i]; return result; } /* * 数组中删除index位置的元素,其他元素顺序不变 */ public static String[] reduceArr(String[] srcArr, int index) { // 删除后的数组,长度-1 String[] result = new String[srcArr.length - 1]; for (int i = 0, j = 0; i < result.length; i++, j++) { if (i == index) //在index位置的元素,跳过拷贝,拷贝下个元素 j++; result[i] = srcArr[j]; } return result; } //将两个数组进行拼接,第一个参数在前,第二个参数数组在后返回一个数组 public static String[] appendArr(String[] before, String[] after) { String[] result = new String[before.length + after.length]; for (int i = 0, j = 0; i < result.length; i++) { if (i < before.length) { result[i] = before[i]; } else { result[i] = after[j]; j++; } } return result; } }
结果为:
[a, b, c, d] [a, b, d, c] [a, c, b, d] [a, c, d, b] [a, d, b, c] [a, d, c, b] [b, a, c, d] [b, a, d, c] [b, c, a, d] [b, c, d, a] [b, d, a, c] [b, d, c, a] [c, a, b, d] [c, a, d, b] [c, b, a, d] [c, b, d, a] [c, d, a, b] [c, d, b, a] [d, a, b, c] [d, a, c, b] [d, b, a, c] [d, b, c, a] [d, c, a, b] [d, c, b, a]