Given a collection of numbers that might contain duplicates, return all possible unique permutations.
For example,
[1,1,2]
have the following unique permutations:
[1,1,2]
, [1,2,1]
, and [2,1,1]
.
分析:全排列的优化,有重复字符时,会有重复排列
class Solution {
vector<vector<int> > ret;
public:
vector<vector<int> > permuteUnique(vector<int> &num) {
DFS(num, 0);
return ret;
}
void DFS(vector<int> &num, int n) {
if(n == num.size()) {
ret.push_back(num);
return;
}
for(int i = n; i < num.size(); i++) {
if(i != n && num[n] == num[i]) continue;
swap(num[n], num[i]);
DFS(num, n + 1);
swap(num[n], num[i]);
}
}
};
上面的算法只考虑的与num[n]比较,相同的情况,并没有考虑num[i] 与num[j]相同的情况。这两种情况都是需要去重的。
class Solution {
vector<vector<int> > ret;
public:
vector<vector<int> > permuteUnique(vector<int> &num) {
sort(num.begin(), num.end());
DFS(num, 0);
return ret;
}
bool isLeftHas(vector<int> &num, int n, int i) {
for(int j = i + 1; j < n; j++) {
if(num[j] == num[i]) return true;
}
return false;
}
void DFS(vector<int> &num, int n) {
if(n == num.size()) {
ret.push_back(num);
return;
}
map<int, bool> hash;
for(int i = n; i < num.size(); i++) {
//if(i != n && num[n] == num[i]) continue;
if(!isLeftHas(num, num.size(), i)) {
swap(num[n], num[i]);
DFS(num, n + 1);
swap(num[n], num[i]);
}
}
}
};
第二种情况去重使用的查找,也可以用hash表来换取查找时间
class Solution {
vector<vector<int> > ret;
public:
vector<vector<int> > permuteUnique(vector<int> &num) {
sort(num.begin(), num.end());
DFS(num, 0);
return ret;
}
void DFS(vector<int> &num, int n) {
if(n == num.size()) {
ret.push_back(num);
return;
}
map<int, bool> hash;
for(int i = n; i < num.size(); i++) {
//if(i != n && num[n] == num[i]) continue;
if(!hash[num[i]]) {
swap(num[n], num[i]);
DFS(num, n + 1);
swap(num[n], num[i]);
hash[num[i]] = true;
}
}
}
};