- 力扣链接:含有重复元素集合的全排列
- 题目:给定一个可包含重复数字的整数集合
nums
,按任意顺序 返回它所有不重复的全排列。 - 思路:
- 这个题需要用到回溯法。
- 用 res 存放最终所有结果的集合,path 存放每次递归得出的结果。
- 布尔型的 visited 数组大小和整型的 nums 数组一样大,用来存放每个数字的状态,ture 为已经访问过,false 为还没有访问过。
- 首先对需要用到的数据进行初始化。将 nums 数组进行排序,n 为数组长度;然后调用回溯函数 backtracking,将当前数字的下标 index 传入回溯函数。
- 在回溯函数中,第一个 if 判断,如果当前下标等于数组长度,就保存当前结果并且return。第二个 for 循环中,第一个 if 判断的是当前数字是否访问过,若访问过,则 continue 跳出本次循环;第二个 if 判断,如果下标 i 合法并且存在两数字相等并且上一个数字没有访问过,则 continue 跳出本次循环。如果两个 if 判断都为 false 则将这个数字放到 path 中,将当前下标对应的 visited 数组的值置为 ture ,接着递归下一个下标 index+1,
class Solution
{
int [] nums;
int n;
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
boolean [] visited;
public List<List<Integer>> permuteUnique(int[] nums)
{
Arrays.sort(nums);
this.nums = nums;
this.n = nums.length;
this.visited = new boolean [n];
backtracking(0);
return res;
}
public void backtracking(int index)
{
if (index == n)
{
res.add(new ArrayList<>(path));
return ;
}
for (int i = 0; i < n; i ++)
{
if (visited[i] == true)
continue;
if (0 < i && nums[i - 1] == nums[i] && visited[i - 1] == false)
continue;
path.add(nums[i]);
visited[i] = true;
backtracking(index + 1);
visited[i] = false;
path.remove(path.size() - 1);
}
}
}