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]
.
分析:
该题与permutation I不同点在于collection中有重复元素,为了生成的结果没有重复的,我们首先要(1)确保在同一个permutation的位置不能放置重复的元素,其次(2)必须保证permutation中某一值的元素个数不超过collection中该值的元素数。对于(1),我们可以先将num按ascending的顺序排序,然后在同一层递归迭代时,跳过重复的元素;对于(2),我们可以用两个unordered_map<int,int> count和cur_count分别记录collection中各值出现的次数和当前permutation中各值出现的次数,只有当count[i] > cur_count[i]时才考虑将i放到当前permutation中。代码如下:
class Solution { public: vector<vector<int> > permuteUnique(vector<int> &num) { vector<vector<int> > result; vector<int> path; unordered_map<int, int> count; unordered_map<int, int> cur_count; for(auto i:num){ if(count.find(i) == count.end()) count[i] = 1; else count[i]++; cur_count[i] = 0; } sort(num.begin(), num.end()); dfs(result, path, num, count, cur_count); return result; } void dfs(vector<vector<int> > &result, vector<int> &path, vector<int> &num, unordered_map<int,int> & count, unordered_map<int,int> &cur_count){ if(path.size() == num.size()){ result.push_back(path); return; } for(int i = 0; i < num.size(); i++){ if(cur_count[num[i]] < count[num[i]] && (i == 0 || num[i-1] != num[i])){ path.push_back(num[i]); cur_count[num[i]]++; dfs(result, path, num, count, cur_count); path.pop_back(); cur_count[num[i]]--; } } } };
迭代版的代码可以直接复用Permutation I的代码。