题目描述
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]
, and [2,1,1]
.
解题思路
在Permutations基础上改进,去除重复。
采用递归。
我们求整个数组的全排列,可以看成求index = 0位置的所有数字,然后对每一种情况求index=[1,num.length - 1]的子数组的全排列,然后递归求解即可(需要去除重复数字的情况)。
代码
public static List<List<Integer>> permute(int[] num) {
List<List<Integer>> list = new ArrayList<List<Integer>>();
Arrays.sort(num);
permutation(num, 0, list);
return list;
}
去除重复排列的递归求解
/**
* 递归求解全排列
*
* @param num
* @param curIndex
* @param pList
*/
public static void permutation(int[] num, int curIndex,
List<List<Integer>> pList) {
if (curIndex == num.length) {
// 已无可交换的数字
List<Integer> list = new ArrayList<Integer>();
// 添加的返回列表中
for (int i = 0; i < num.length; i++) {
list.add(num[i]);
}
pList.add(list);
} else {
for (int i = curIndex; i < num.length; i++) {
boolean flag = true;
if(i != curIndex){
if(num[curIndex] == num[i]){
flag = false;
} else {
//判断是否已经出现在前面的交换项中,避免重复
for(int j = curIndex + 1; j < i;j++){
if(num[j] == num[i]){
flag = false;
break;
}
}
}
}
if (flag) {
// 交换当前子数组的num[curIndex]和num[i]
int temp = num[curIndex];
num[curIndex] = num[i];
num[i] = temp;
// [curIndex + 1, num.length - 1]的全排列
permutation(num, curIndex + 1, pList);
// 交换当前子数组的num[curIndex]和num[i],还原成初始状态
temp = num[curIndex];
num[curIndex] = num[i];
num[i] = temp;
}
}
}
}