难度中等581
给定一个可包含重复数字的序列 nums
,按任意顺序 返回所有不重复的全排列。
示例 1:
输入:nums = [1,1,2] 输出: [[1,1,2], [1,2,1], [2,1,1]]
示例 2:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
提示:
1 <= nums.length <= 8
-10 <= nums[i] <= 10
通过次数135,951提交次数216,891
思路和46相似,只是加了一层同层剪枝,需要替换的那个位置不能被后面的相同值重复替换,也就是说f位置的值必须唯一
解答成功:
执行耗时:2 ms,击败了67.85% 的Java用户
内存消耗:39.3 MB,击败了28.90% 的Java用户
class Solution {
List<List<Integer>> res =new ArrayList<>();
public void func(List<Integer> nums,int f){
//nums是原来的数组。f用来标识当前替换的位置
//递归退出条件是当前的f替换的位置已经到最后一个了
if (f==nums.size()-1) {
res.add(new ArrayList<>(nums));
return;
}
List<Integer> visit =new ArrayList<>();
//用来判断当前层 f位置被哪些值替换过
int temp=0;
for (int i = f; i < nums.size(); i++) {
//同层剪枝,如果f位置被i值的位置替换过则跳过该值
if(i>f&&visit.contains(nums.get(i))) {
continue;
}
//使用i位置的数替换f 做本次的运算
temp=nums.get(i);
nums.set(i, nums.get(f));
nums.set(f,temp);
visit.add(temp);
//继续选择下一个位置做填充
func(nums, f+1);
//交换回原来
temp=nums.get(f);
nums.set(f, nums.get(i));
nums.set(i,temp);
}
}
public List<List<Integer>> permuteUnique(int[] nums) {
List<Integer> new_nums= new ArrayList<>();
for (int i = 0; i < nums.length; i++) {
new_nums.add(nums[i]);
}
func(new_nums, 0);
return res;
}
}