Permutations,全排列
问题描述:给定一个数组,数字中数字不重复,求所有全排列。
算法分析:可以用交换递归法,也可以用插入法。
递归法:例如,123,先把1和1交换,然后递归全排列2和3,然后再把1和1换回来。1和2交换,全排列1和3,再把1和2交换回来。1和3交换,全排列2和1,再把1和3交换回来。
//递归方法 public List<List<Integer>> permute2(int[] num) { List<List<Integer>> result = new ArrayList<>(); permute(num, 0, result); return result; } void permute(int[] num, int start, List<List<Integer>> result) { if (start == num.length) { ArrayList<Integer> item = convertArrayToList(num); //List<int[]> list = Arrays.asList(num);这个方法适合String,而不适合int,会把int[]当成一个元素加入list result.add(item); } for (int j = start; j < num.length; j++) { //递归方法,首先1和1交换,求除nums[1]外的序列的全排列,然后1和1再交换回来。1和2交换,求除了nums[1]之外的序列的全排列,然后1和2再交换回来。 swap(num, start, j); permute(num, start + 1, result); swap(num, start, j); } } private ArrayList<Integer> convertArrayToList(int[] num) { ArrayList<Integer> item = new ArrayList<Integer>(); for (int h = 0; h < num.length; h++) { item.add(num[h]); } return item; } private void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; }
插入法:例如123,1开始有1个插入位置得到序列[1],然后2有两个插入位置,得到序列[2,1],[1,2],然后3有三个插入位置,得到[3,2,1],[2,3,1],[2,1,3],[3,1,2],[1,3,2],[1,2,3]
public List<List<Integer>> permute(int[] num) { List<List<Integer>> result = new ArrayList<>(); //start from an empty list result.add(new ArrayList<Integer>()); for (int i = 0; i < num.length; i++) { List<List<Integer>> current = new ArrayList<>(); for (List<Integer> l : result) { //插入size+1个位置 for (int j = 0; j < l.size()+1; j++) { l.add(j, num[i]); ArrayList<Integer> temp = new ArrayList<Integer>(l); current.add(temp); l.remove(j); } } result = new ArrayList<>(current); } return result; }