46. Permutations
一、题目
1、审题
2、分析:
输入一个不重复整形数组,求他的全排序
二、解答
1、思路:
方法一:利用递归实现全排序,先固定第一个值,在对后边全排序...最终当固定的值为最大下标时,则此时即得一排序。
class Solution { public List<List<Integer>> permute(int[] nums) { Arrays.sort(nums); List<List<Integer>> resultList = new ArrayList<List<Integer>>(); callAllPerm(resultList, nums, 0, nums.length - 1); return resultList; } // 获得全排序 private void callAllPerm(List<List<Integer>> resultList, int[] nums, int from, int to) { if(from == to) { // add List<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < nums.length; i++) { list.add(nums[i]); } resultList.add(list); } else { for (int i = from; i <= to; i++) { swap(nums, i, from); callAllPerm(resultList, nums, from + 1, to); swap(nums, i, from); } } } // 交换数组元素 private void swap(int[] nums, int tempIndex, int index) { int temp = nums[tempIndex]; nums[tempIndex] = nums[index]; nums[index] = temp; } }
方法二: 将数组排成升序后,依次求得比这一个数组数字大的下一个数字数组,最终这些所有的字典序的数组即为全排序。
求字典序步骤如下,例如对于 21543而言,其下一个排序序列求法为:
①、从右向左找到第一个能有升序的位置i ,此时,x = ai = 1;
②、在 i 的右侧找到比 ai 大的最小的一个元素位置 j, 此时, y = aj = 3;(其实就是从右向左查找的第一个比 ai 大的数就是了)
③、交换 x 与 y
④、将 i + 1 到最后位置的数组元素进行翻转。
class Solution { public List<List<Integer>> permute(int[] nums) { List<List<Integer>> resultList = new ArrayList<List<Integer>>(); if(nums.length == 0) return resultList; Arrays.sort(nums); addTargetList(resultList, nums); //加上原排序 helper(resultList, nums, nums.length - 2); return resultList; } /* * 1、交换 * 2、翻转 * 3、i 改变 */ private void helper(List<List<Integer>> resultList, int[] nums, int index) { if(index < 0) return; int tempIndex = -1; for (int i = nums.length -1; i > index; i--) { // 找比 index 大的最小值 if(nums[i] > nums[index]) { tempIndex = i; break; } } if(tempIndex != -1) { swap(nums, tempIndex, index); //交换 reverse(nums, index+1); // 翻转 addTargetList(resultList, nums); // 添加 helper(resultList, nums, nums.length - 2); // 重新递归 } else { helper(resultList, nums, index - 1); // index 向左移动 } } private void addTargetList(List<List<Integer>> resultList, int[] nums) { List<Integer> list = new ArrayList<Integer>(); for (int i = 0; i < nums.length; i++) { list.add(nums[i]); } resultList.add(list); } // 翻转从 index 开始的数组元素 private void reverse(int[] nums, int index) { if(index < nums.length - 1) { for (int i = index, j= nums.length-1; j > i; i++, j--) { swap(nums, i, j); } } } // 交换数组元素 private void swap(int[] nums, int tempIndex, int index) { int temp = nums[tempIndex]; nums[tempIndex] = nums[index]; nums[index] = temp; } }