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