刚刚又刷了一道上一题的加强版,感觉难度还是有一些的,下面就和大家分享一下经验吧!
题目如下:
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]
]
题意分析:
给定一个可能包含相同整数的集合,请返回所有的唯一排列组合。
方法一(递归回溯法)
与“https://blog.csdn.net/Vensmallzeng/article/details/96428514”的方法一类似,不过在递归前应对nums进行排序,也需要在递归函数中判断前面一个数和当前的数是否相等,如果相等且前面一个数对应的visited值为1,当前的数字才能使用,否则需要跳过,这样就可以去掉重复的组合情况了。
解题代码如下:
class Solution{
private:
vector<vector<int>> res;
vector<bool> visited;
void FindpermuteUnique(vector<int>& nums, int k, vector<int>& temp){
if (k >= nums.size())
{res.push_back(temp);
return;}
for (int i = 0; i < nums.size(); i++) {
cout<<"i:"<<i<<"123"<<visited[i]<<endl;
if (!visited[i]){
cout<<"i:"<<i<<visited[i]<<endl;
if(i > 0 && nums[i]==nums[i-1] && visited[i-1] == 0) continue;
temp.push_back(nums[i]);
visited[i] = true;
FindpermuteUnique(nums, k+1,temp);
visited[i] = false;;
temp.pop_back();
}
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums){
if(nums.size()==0) return res;
vector<int> temp;
sort(nums.begin(), nums.end());
//visited一定要初始化
visited = vector<bool>(nums.size(), false);
FindpermuteUnique(nums, 0,temp);
return res;
}
};
提交后的结果如下:
方法二(递归交换法)
与“https://blog.csdn.net/Vensmallzeng/article/details/96428514”的方法二类似,不过需要用Set来保存结果以便去掉重复项,同时在递归函数中的swap之前,需要判断一下,如果i和start不相同且nums[i]和nums[start]相同,则跳过该情况继续下一个循环。
解题代码如下:
class Solution{
public:
vector<vector<int>> permuteUnique(vector<int> nums) {
set<vector<int>> res;
if (nums.size() == 0) return {{}};
FindpermuteUnique(nums, 0, res);
return vector<vector<int>> (res.begin(), res.end());
}
void FindpermuteUnique(vector<int> nums, int start, set<vector<int>>& res){
if(start == nums.size()) {
res.insert(nums);
return;
}
for (int i = start; i < nums.size(); i++) {
if (i != start && nums[start] == nums[i]) continue;
swap(nums[start], nums[i]);
FindpermuteUnique(nums, start+1, res);
swap(nums[start], nums[i]);
}
}
};
提交后的结果如下:
日积月累,与君共进,增增小结,未完待续。