Given a collection of numbers that might contain duplicates, return all possible unique permutations.
Example:
Input: [1,1,2]
Output:
[
[1,1,2],
[1,2,1],
[2,1,1]
]
题目: 对给定的数组nums
进行全排列,其中nums
可能包含重复的元素。返回的全排列集合中应是无重复的解的(去重的)。
思路: 同Permutations。记p
为一个待填充的排列,当p
的长度等于数组nums
的长度时,表明已经找到了一种排列。针对p
的同一个位置,为了不出现重复的排列,回溯返回后继续循环时需要跳过已经使用过的元素值。比如p[1]
以值为3
进行递归,当递归回溯到p[1]
这个状态时,p[1]
的下一个取值应该跳过值同样为3
的元素(因此最开始需要对nums
进行排序),然后再递归进入p[2]
状态,依次类推。
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
int n = nums.size();
if(n == 0) return {};
sort(nums.begin(), nums.end());
vector<vector<int>> res;
vector<int> vec;
vector<bool> used(n, false);
helper(nums, res, vec, used);
return res;
}
private:
void helper(vector<int>& nums, vector<vector<int>>& res, vector<int>& vec,
vector<bool>& used){
if(vec.size() == nums.size()){
res.push_back(vec);
return;
}
for(int i = 0; i < nums.size(); ++i){
if(used[i] == true)
continue;
// 如果当前数与前一个数相等,并且前一个没被使用过,则跳过这个重复的元素
if(i > 0 && nums[i] == nums[i-1] && used[i-1] == false)
continue;
used[i] = true;
vec.push_back(nums[i]);
helper(nums, res, vec, used);
vec.pop_back();
used[i] = false;
}
return;
}
};
int main()
{
Solution sln;
vector<int> testcase{ 1,1,2,2,2,2,2,2,2,2 };
vector<vector<int>> res;
res = sln.permuteUnique(testcase);
for (auto vec : res) {
for (auto i : vec)
cout << i << " ";
cout << endl;
}
std::cout << "Hello World!\n";
}