题目
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
示例 1:
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]
解题思路
本题题意清晰、明了,找出所有的所有不重复的全排列
- 容易想到使用回溯算法
- 因为数组中含有重复元素,所以全排列后可能会有重复,需要去重
代码
class Solution {
private List<List<Integer>> res = new ArrayList<>();
/** 用于去除排列后的重复项 */
private Set<String> set = new HashSet<>();
public List<List<Integer>> permuteUnique(int[] nums) {
// 回溯
backtrack(nums, new ArrayList<>());
return res;
}
/**
* 回溯
*
* @param nums 待全排列的数组
* @param idxList 索引列表:用于判断当前元素是否已经排列过
*/
private void backtrack(int[] nums, List<Integer> idxList) {
// 如果所有元素都排列过,处理结果
if (idxList.size() == nums.length) {
List<Integer> list = new ArrayList<>();
// 通过索引list,构建元素list
for (int index : idxList) list.add(nums[index]);
// 因为数组中含有重复元素,所以全排列后可能会有重复,需要去重
if (!set.contains(list.toString())) {
set.add(list.toString());
res.add(list);
}
return;
}
for (int i = 0; i < nums.length; i++) {
// 如果nums[i]已经排序过,则跳过
if (idxList.contains(i)) continue;
idxList.add(i);
backtrack(nums, idxList);
idxList.remove(idxList.size() - 1);
}
}
}