Permutations II
Mar 17 '12
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]
.
思路一:用set来装vector,可以直接用Permutations的代码,但并没有从根本上解决产生重复排列的问题,效率也不高
class Solution {
public:
int factorial(int n)
{
return (n==1)?1:n*factorial(n-1);
}
void nextPermutation(vector<int> &num) {
int i = 0;
int k = num.size();
while(k-->=1)
{
if(num[k] > num[k-1])
{
i = k;
break;
}
}
int j= i-1;
k = num.size();
while(k-- != i-1)
{
if(num[k] > num[i-1]) {
j = k;
break;
}
}
swap(num[i-1],num[j]);
reverse(num.begin()+i,num.end());
}
vector<vector<int> > permuteUnique(vector<int> &num) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<vector<int>> ret;
set<vector<int>> set;
int N = factorial(num.size());
for(int i = 0;i < N;i++){
set.insert(num);
nextPermutation(num);
}
ret.insert(ret.end(),set.begin(),set.end());
return ret;
}
};
800 milli secs
思路二:还是在permute的基础上,重点见注释
class Solution {
public:
vector<vector<int> > permuteUnique(vector<int> &num) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
vector<vector<int>> ret;
sort(num.begin(),num.end()); //重点在这步排序
while(1){
ret.push_back(num);
int i = 0;
int k = num.size();
while(k-->=1)
{
if(num[k] > num[k-1]) //这里是>号,所以在排好序的情况下是否有重复并无影响
{
i = k;
break;
}
}
if(k==-1) break; //判断是否生成了所有排列
int j= i-1;
k = num.size();
while(k-- != i-1)
{
if(num[k] > num[i-1]) {
j = k;
break;
}
}
swap(num[i-1],num[j]);
reverse(num.begin()+i,num.end());
}
return ret;
}
};
160 milli secs
其它方法暂不实现,有空再讨论吧
可以看一下这篇http://www.cnblogs.com/remlostime/archive/2012/11/13/2768816.html,提到DFS的方法