给定一个可包含重复数字的序列,返回所有不重复的全排列。
示例:
输入: [1,1,2]
输出:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
解法一:建立索引与值得字典,将这个问题转化成唯一索引的全排列,这时候还是会存在重复的问题,再用去重的方法解决;但是时间复杂度很高,没有通过;
class Solution {
public:
vector<vector<int>>res;
vector<vector<int>> permuteUnique(vector<int>& nums) {
map<int, int>mymap;
vector<int>tmp2;
int N = nums.size();
for(int i=0;i<N;i++){
mymap[i] = nums[i];
//tmp2.push_back(i);
}
vector<int> tmp;
backtrace(tmp,nums,mymap,tmp2);
return res;
}
void backtrace(vector<int>tmp, vector<int>nums, map<int,int>mymap,vector<int>tmp2){
if(tmp.size()==nums.size()&&find(res.begin(),res.end(),tmp)==res.end()){
res.push_back(tmp);
}
for(int i=0;i<nums.size();i++){
if(find(tmp2.begin(),tmp2.end(),i)==tmp2.end()){
tmp2.push_back(i);
tmp.push_back(mymap[i]);
backtrace(tmp,nums,mymap,tmp2);
tmp2.pop_back();
tmp.pop_back();
}
}
}
};
同样的方法,就是将数组的数字和出现的次数做成字典,这样按照出现次数可以判断它是不是在路径中了;
class Solution {
public:
vector<vector<int>>res;
vector<vector<int>> permuteUnique(vector<int>& nums) {
map<int, int>mymap;
vector<int>tmp;
int N = nums.size();
for(int i=0;i<N;i++){
mymap[nums[i]]++;
//tmp2.push_back(i);
}
backtrace(nums,tmp,mymap);
return res;
}
void backtrace(vector<int>nums,vector<int>tmp, map<int,int>&mymap){
if(tmp.size()==nums.size()){
res.push_back(tmp);
}
for(auto& m:mymap){
if(m.second==0){
continue;
}
m.second--;
tmp.push_back(m.first);
backtrace(nums,tmp,mymap);
m.second++;
tmp.pop_back();
}
}
};