题目描述:
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] ]
分析:
题意:给定一个可重复整型数集合,返回它所有可能的不重复排列。
思路:这道题是LeetCode 47的进化版本,区别在于出现了重复数字。我们仍然采用DFS搜索的方法,这里给出两个版本的代码:①直接使用DFS搜索,在缓存结果时考虑存储pair(i, nums[i])(即用数字的下标来区别重复数字),代码会超时;②使用DFS + map的组合,其中map用来统计不同数字出现的频数,从而区别相同的数字,代码通过。
代码(DFS,超时):
#include <bits/stdc++.h>
using namespace std;
// Time Limit Exceeded
class Solution {
private:
vector<vector<int>> ans;
vector<pair<int, int>> res;
void DFS(vector<int>& nums, int n, int k){
// Exceptional Case:
if(k == n){
vector<int> vec;
for(auto p: res){
vec.push_back(p.second);
}
if(find(ans.begin(), ans.end(), vec) == ans.end()){
ans.push_back(vec);
}
return;
}
for(int i = 0; i <= n - 1; i++){
if(find(res.begin(), res.end(), make_pair(i, nums[i])) == res.end()){
res.push_back(make_pair(i, nums[i]));
DFS(nums, n, k + 1);
res.pop_back();
}
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
ans.clear();
res.clear();
int n = nums.size();
// Exceptional Case:
if(n == 0){
return ans;
}
DFS(nums, n, 0);
return ans;
}
};
代码(DFS + map):
// DFS + map
// map: eliminates the difference between the order of the same numbers
class Solution{
private:
vector<vector<int>> ans;
vector<int> res;
map<int, int> m;
void DFS(vector<int>& nums, int n, int k){
// Exceptional Case:
if(k == n){
ans.push_back(res);
return;
}
// for(auto p: m){ will cause an error!
for(auto &p: m){
if(p.second >= 1){
p.second--;
res.push_back(p.first);
DFS(nums, n, k + 1);
res.pop_back();
p.second++;
}
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
ans.clear();
res.clear();
m.clear();
int n = nums.size();
// Exceptional Case:
if(n == 0){
return ans;
}
// map
for(int key: nums){
m[key]++;
}
DFS(nums, n, 0);
return ans;
}
};