题目:
Given a collection of integers that might contain duplicates, nums, return all possible subsets.
Note:
- Elements in a subset must be in non-descending order.
- 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], [] ]
思路:
方法一:
dfs解法。注意到处理第三个元素2时,因为前面已经处理了一次2,所有第三层中,我们只在已经添加过2的集合{1,2}、{2}上再添加2,而没有在集合{1}, {}上添加2(画叉叉的那么分支),假设下面还有一个2,那么我们只在第四层的包含两个2的集合{1,2,2}、{2,2}上再添加2,其它都不添加。因此dfs时,如果当前处理的数字前面出现了k次,那么我们要处理的集合中必须包含k个该元素。
/** * @param {number[]} nums * @return {number[][]} */ var subsetsWithDup = function(nums) { var res=[]; nums.sort(function(a,b){return a-b;}); var tempRes=[]; dfs(nums,0,tempRes); return res; function dfs(nums,iEnd,tempRes){ var temp=[]; for(var i=0;i<tempRes.length;i++){ temp[i]=tempRes[i]; } if(iEnd==nums.length){ res.push(temp); return; } var firstSame=iEnd; while(firstSame>=0&&nums[firstSame]==nums[iEnd]){ firstSame--; } firstSame++; sameNum=iEnd-firstSame; if(sameNum==0||(temp.length>=sameNum&&tempRes[tempRes.length-sameNum]==nums[iEnd])){ //选择 temp.push(nums[iEnd]); dfs(nums,iEnd+1,temp); temp.pop(); } //不选 dfs(nums,iEnd+1,temp); } };
方法二:
在上一题算法2的基础上,如果当前处理的元素没有出现过,则把前面得到的所有集合加上该元素;如果出现过,则只把上一轮处理的集合加上该元素。比如处理第二个2时(二叉树第三层),我们只把上一轮添加过数字的集合{1,2}、{2}再添加一个2加入结果中,{1}、{}是从上一层直接继承下来的,所以不作处理。