题目描述:
给定一个可包含重复数字的序列
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]]
分析:
最难的部分是去重部分,是舍弃树层部分重复的数还是树枝部分重复的数?首先引入used标记数组,used[i]=true表示这个数被选择了,used[i]-false表示这个数被舍弃了。那么我们看搜索树的过程中的if分支,used[i]表示这个数已经选择了,那么在子树的过程不应该出现这个数;i>0 && nums[i-1]==nums[i] && !used[i-1],首先i>0防止used[i-1]溢出,其次当nums[i-1]==nums[i]表示可能会出现树层重复的情况(因为可能出现used[i-1]==true的情况时,只可能出现在树枝之间,不可能出现树层之间,因为树层之间只能出现一个数),如果used[i-1]==false,即在nums[i-1]结点时,所有情况已经遍历过了,那么在nums[i]结点时,应该跳过这个结点。
代码:
class Solution {
public:
vector<vector<int>> f;
vector<int> temp;
void travel(vector<int> &nums,vector<bool> &used){
if(temp.size()==nums.size()){
f.push_back(temp);
return;
}
for(int i=0;i<nums.size();i++){
if(used[i] || (i>0 && nums[i-1]==nums[i] && !used[i-1])) continue;
used[i]=true;
temp.push_back(nums[i]);
travel(nums,used);
temp.pop_back();
used[i]=false;
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<bool> used(nums.size(),false);
travel(nums,used);
return f;
}
};