Permutations II
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], [2,1,1] ]解题技巧:
该题与Permutation基本相同,不同之处在于这道题中输入数组中可能包含重复数字,若采用Permutation的解法,会产生重复的结果。因此,需要在Permutation的解法中加一些处理:首先,将输入数组排序,保证重复的数字相邻,然后在递归函数中保证相同的元素按序被访问,也就是判断当前的数与前一个数是否相等,如果相等,前面的数必须已经使用了,当前的数字才能使用,否则需要跳过,这样就不会产生重复排列了。
代码:
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;
vector< vector<int> > res;
bool *flag;
void dfs(vector<int>& nums, vector<int> res0)
{
int len = nums.size();
if(res0.size() == len )
{
res.push_back(res0);
return;
}
for(int i = 0; i < len; i ++)
{
if(flag[i] == true) continue;
if (i > 0 && nums[i] == nums[i - 1] && flag[i-1] == false ) continue; //通过限定相同数字的使用次序,避免重复序列
flag[i] = true;
res0.push_back(nums[i]);
dfs(nums, res0);
res0.pop_back();
flag[i] = false;
}
}
vector< vector<int> > permuteUnique(vector<int>& nums)
{
vector<int> res0;
flag = new bool [nums.size()];
for(int i = 0; i < nums.size(); i ++)
{
flag[i] = false;
}
sort(nums.begin(), nums.end()); //排序,使得相同的数字相邻
dfs(nums, res0);
return res;
}
int main()
{
int num;
vector<int> nums;
while(cin>>num)
{
nums.push_back(num);
}
res = permuteUnique(nums);
for(int i = 0 ; i < res.size(); i ++)
{
for(int j = 0; j < res[i].size(); j ++)
{
cout<<res[i][j]<<' ';
}
cout<<endl;
}
}