BM56 有重复项数字的全排列
描述
给出一组可能包含重复项的数字,返回该组数字的所有排列。结果以字典序升序排列。
数据范围: 0<n≤80<n≤8 ,数组中的值满足 −1≤val≤5−1≤val≤5
要求:空间复杂度 O(n!)O(n!),时间复杂度 O(n!)O(n!)
示例1
输入:
[1,1,2]
返回值:
[[1,1,2],[1,2,1],[2,1,1]]
示例2
输入:
[0,1]
返回值:
[[0,1],[1,0]]
题解
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param num int整型一维数组
* @return int整型ArrayList<ArrayList<>>
*/
public ArrayList<ArrayList<Integer>> permuteUnique (int[] num) {
// 排序
Arrays.sort(num);
// 标记该数字是否被使用
boolean [] flag = new boolean[num.length];
ArrayList<ArrayList<Integer>>res = new ArrayList<>();
LinkedList<Integer>list = new LinkedList<>();
getRes(res, list, num, flag);
return res;
}
public void getRes(ArrayList<ArrayList<Integer>>res, LinkedList<Integer> list,
int[] num, boolean []flag ) {
// 是否使用全部数字
if (list.size() == num.length) {
// 全部使用
res.add(new ArrayList<>(list));
return;
}
// 遍历num
for (int i = 0; i < num.length; i++) {
// 已经使用 跳过
if (flag[i]) {
continue;
}
// 一个数字不能被重复选择
if (i > 0 && num[i - 1] == num[i] && flag[i - 1]) {
//当前的元素num[i]与同一层的前一个元素num[i-1]相同且num[i-1]已经用过了
continue;
}
// 添加当前数字
list.add(num[i]);
// 标记当前数字
flag[i] = true;
// 递归
getRes(res, list, num, flag);
// 撤销添加
list.removeLast();
// 撤销标记
flag[i] = false;
}
}
}