Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note: The solution set must not contain duplicate subsets.
For example, If nums = [1,2,2], a solution is:
[ [2], [1], [1,2,2], [2,2], [1,2], [] ]
s思路: 1. 列举的长度可变,就是不规则的,正常的需要双重循环,和subsets I一样,用一个for+recursive就可以了。关键是如何去重复?首先,需要排序;然后比较相邻两个元素是否相同。判断条件是:
if(i>0&&nums[i]==nums[i-1]&&i!=idx) continue;这个之前讨论过,不怕麻烦再来一次。因为整个backtracking就是在两个方向上做遍历:一个是广度,用for循环,代表结果中同一个位置(i)放不同值的情况;一个是深度,用recursive,代表不同的位置。在判断是否重复,就是判断在广度遍历中,即:用for循环时是否在同一个位置尝试放相同的值,这就必然导致重复;而在不同位置是可以放相同的值,并不导致重复。 2. 上文中,nums[i]==nums[i-1]&&i!=idx表示连续两个数相等,并且这个坐标不等于for循环开始的值,表示i是在同一个位置尝试其他值!所以是广度遍历。i>0是加保护用的!
class Solution { public: void helper(vector<vector<int>>&res,vector<int>&nums,vector<int>&cur,int idx){ res.push_back(cur); for(int i=idx;i<nums.size();i++){ if(i>0&&nums[i]==nums[i-1]&&i!=idx) continue; cur.push_back(nums[i]); helper(res,nums,cur,i+1); cur.pop_back(); } } vector<vector<int>> subsetsWithDup(vector<int>& nums) { // sort(nums.begin(),nums.end()); vector<int> cur; vector<vector<int>> res; helper(res,nums,cur,0); return res; } };