刚刚又刷了一道上一题的加强版,感觉难度还是有一些的,下面就和大家分享一下经验吧!
题目如下:
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]); } } };提交后的结果如下:
日积月累,与君共进,增增小结,未完待续。