题目
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
思路
最开始想把所有的全排列都找出来,然后再去重,结果遗憾超时
要想保证没有重复的排列,那么就需要在path的每个位置,每个重复的数只能出现一次
因此可以先对数组进行排序,保证相同的数字都相邻,然后每次填入的数一定是这个数所在重复数集合中「从左往右第一个未被填过的数字」。
以[1,1,2]为例,先选第一个1和先选第二个1产生的分支是一模一样的,这就是产生重复的原因
class Solution {
public:
vector<int> path;
bool st[10];
void dfs(vector<vector<int>> &res,vector<int>& nums,int u,int n){ // u是当前的位置,n是nums的长度
if(u==n){
res.push_back(path);
return;
}
for(int i=0;i<n;i++){
//当前的数已经被用过,或者在他左边和这个数相同的数已经被用过,那么就忽略掉这个数
if(st[i]==1||(i>0&&nums[i-1]==nums[i]&&st[i-1]!=0)){
continue;
}
st[i]=1;
path.push_back(nums[i]);
dfs(res,nums,u+1,n);
st[i]=0;
path.pop_back();
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<vector<int>> res;
sort(nums.begin(),nums.end());
int n = nums.size();
dfs(res,nums,0,n);
return res;
}
};