【数组】Subsets II

题目:

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}、{}是从上一层直接继承下来的,所以不作处理。

posted @ 2016-01-04 22:43  很好玩  阅读(264)  评论(0编辑  收藏  举报