https://oj.leetcode.com/problems/permutations-ii/
http://blog.csdn.net/linhuanmars/article/details/21570835
public class Solution { public List<List<Integer>> permuteUnique(int[] num) { // Solution A: // return permuteUnique_Swap(num); // Solution B: return permuteUnique_NP(num); } //////////////////////// // Solution B: NP // private List<List<Integer>> permuteUnique_NP(int[] num) { Arrays.sort(num); boolean[] used = new boolean[num.length]; List<List<Integer>> results = new ArrayList<>(); permuteUnique_NPhelp(num, used, new ArrayList<Integer>(), results); return results; } private void permuteUnique_NPhelp(int[] num, boolean[] used, List<Integer> items, List<List<Integer>> results) { if (items.size() == num.length) { results.add(new ArrayList<Integer>(items)); return; } for (int i = 0 ; i < num.length ; i ++) { // If num[i] equals to some value been used before // continue // If used[i - 1] == true, that is the first time num[i] occurs. if (i > 0 && !used[i - 1] && num[i] == num[i - 1]) continue; if (used[i]) continue; used[i] = true; items.add(num[i]); permuteUnique_NPhelp(num, used, items, results); used[i] = false; items.remove(items.size() - 1); } } //////////////////////// // Solution A: Recursive swap // private List<List<Integer>> permuteUnique_Swap(int[] num) { List<List<Integer>> result = new ArrayList<>(); perm(num, 0, result); return result; } private void perm(int[] n, int start, List<List<Integer>> result) { int len = n.length; if (start >= len) { // A result found. result.add(listof(n)); } for (int i = start ; i < len ; i ++) { // If we have any dups from start to i. // No need to continue recursion // // 注意不要误以为以下两种做法能够去重: // (1)最开始先对数组进行排序,以后每次交换时,只要保证当前要交换的元素和前一个元素不同,这种做法是错误的. // 虽然开始进行了排序,但是元素的交换会使数组再次变的无序 // (2)每次进入递归函数permuteRecur时,对从当前索引开始的子数组排序,这种做法也是错误的. // 因为每次交换元素后,我们要恢复交换的元素,如果在递归函数内排序,就不能正确的恢复交换的元素。 if (unique(n, start, i)) { swap(n, i, start); perm(n, start + 1, result); swap(n, i, start); } } } private boolean unique(int[] n, int start, int end) { for (int i = start ; i < end ; i ++) { if (n[i] == n[end]) return false; } return true; } private List<Integer> listof(int[] n) { List<Integer> toReturn = new ArrayList<>(n.length); for (int i : n) toReturn.add(i); return toReturn; } private void swap(int[] n, int i , int j) { int t = n[i]; n[i] = n[j]; n[j] = t; } }
原文地址:http://7371901.blog.51cto.com/7361901/1598601