Given a collection of distinct numbers, return all possible permutations.
For example,[1,2,3]
have the following permutations:
[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
分析:
当array里没有重复数的时候,要找出所有的排列,我们可以把每个数放在第一位,然后获得后面的数排列。利用递归原理,为了获得后面的数的排列,把剩余的数都逐个放在第二位,,,,直到一个新的数组填满。
1 public class Solution { 2 public List<List<Integer>> permute(int[] nums) { 3 List<List<Integer>> list = new ArrayList<List<Integer>>(); 4 permutation(nums, 0, nums.length, list); 5 return list; 6 } 7 8 void permutation(int[] arr, int index, int size, List<List<Integer>> list) { 9 if (index == size) { //填满了 10 addToList(arr, list); 11 return; 12 } 13 for (int i = index; i < size; i++) { 14 swap(arr, i, index); // 把每个数都放在当前数组的“第一位” 15 permutation(arr, index + 1, size, list); //获得后面的数的排列 16 swap(arr, i, index); 17 } 18 } 19 20 void addToList(int[] arr, List<List<Integer>> list) { 21 ArrayList<Integer> temp = new ArrayList<Integer>(); 22 for (int i : arr) { 23 temp.add(i); 24 } 25 list.add(temp); 26 } 27 28 void swap(int[] arr, int idx1, int idx2) { 29 int temp = arr[idx1]; 30 arr[idx1] = arr[idx2]; 31 arr[idx2] = temp; 32 } 33 }
Permutations II
Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,[1,1,2]
have the following unique permutations:
[ [1,1,2], [1,2,1], [2,1,1] ]
分析:
在这个问题里,因为有了重复数字的出现,所以,当把每个数字放在当前数组的第一位的时候,我们需要确保没有重复,我们可以用hashset来check是否重复。
1 public class Solution { 2 public List<List<Integer>> permuteUnique(int[] nums) { 3 List<List<Integer>> list = new ArrayList<List<Integer>>(); 4 Arrays.sort(nums); 5 permutation(nums, 0, nums.length, list); 6 return list; 7 } 8 9 void permutation(int[] arr, int index, int size, List<List<Integer>> list) { 10 if (index == size) { 11 addToList(arr, list); 12 return; 13 } 15 // when swaping arr[i] with arr[index], we need to make sure the uniqueness of arr[i], 16 // otherwise, we will have duplicates. 17 HashSet<Integer> set = new HashSet<Integer>(); 18 for (int i = index; i < size; i++) { 19 if (!set.contains(arr[i])) { 20 set.add(arr[i]); 21 swap(arr, i, index); 22 permutation(arr, index + 1, size, list); 23 swap(arr, i, index); 24 } 25 } 26 } 27 28 void swap(int[] arr, int idx1, int idx2) { 29 int temp = arr[idx1]; 30 arr[idx1] = arr[idx2]; 31 arr[idx2] = temp; 32 } 33 34 void addToList(int[] arr, List<List<Integer>> list) { 35 ArrayList<Integer> temp = new ArrayList<Integer>(); 36 for (int i : arr) { 37 temp.add(i); 38 } 39 list.add(temp); 40 } 41 }
Note: 当时还考虑到用下面的方法来去重复,但是总是通不过,后来才发现,当swap operation完毕以后,后面部分数组已经不是单调递增的了。但是很欣慰的是,自己还是把问题解决了,而且个人认为,上面所讲的方法应该是最容易理解也是最简单的方法。
1 void permutation(int[] arr, int index, int size, List<List<Integer>> list) { 2 if (index == size) { 3 addToList(arr, list); 4 } else { 5 for (int i = index; i < size; i++) { 6 // arr[i] == arr[index] 不能做,是因为如果和index交换以后,arr[i]有和arr[index]相等,最后一定会重复。 7 // arr[i - 1] == arr[i] 也不能做,是因为前面那个值arr[i-1]已经与index交换过了,如果arr[index]和arr[i]再次交换,最后也会重复。 8 if (i != index && (arr[i] == arr[index] || arr[i - 1] == arr[i])) 9 continue; 10 swap(arr, i, index); 11 permutation(arr, index + 1, size, list); 12 swap(arr, i, index); 13 } 14 } 15 }
参考请注明出处:cnblogs.com/beiyeqingteng