[lintcode] 18. Subsets [Medium]

描述

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

 

样例

Input: [1,2,2]

Output:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

挑战

你可以同时用递归与非递归的方式解决么?

 

思路

典型的dfs,但是没那么容易想清楚树的结构。在做无重复的permutation的时候,其实bfs、dfs都可以。但是要想清楚的是树的层次不是一个元素的选择作为一层(两枝分别为选和不选),而是真正加入了一个元素的时候作为一层。比如[1,2,2]和[1,2,3]中2和3在同一层。是同一个结点的后继。

去重的思路是对于重复的元素,只加入第一个,剩下的全部跳过。这时候可能会考虑比如在[1,2,2,2,3]的情境下,[2,2,2,3]是怎么出来的。因为对于第二个2来说,它的位置一定在第一个2的后面,所以它和3是同级的。因为第三个2必须在第二个2选了之后才能选,所以第三个2是第二个2的后继,不在当前考虑范围内。

因此第一个2的枝丫只能是第二个2,和除了2之外未被选择的数。这样问题就解决了。

(p.s 我觉得这道题对dfs的要求很高,理解必须非常深入才行)

 

代码

class Solution {
public:
    /**
     * @param nums: A set of numbers.
     * @return: A list of lists. All valid subsets.
     */

    vector<vector<int>> ans;
    
    void dfs( int startPos, vector<int> &nums, vector<int>& subset )
    {
        ans.emplace_back(subset); //no choose
        
        for( int i=startPos; i<nums.size(); ++i )
        {
            if( i!=startPos && nums[i] == nums[i-1] )
            {
                continue;
            }
            
            subset.emplace_back( nums[i] );
            dfs( i+1, nums, subset );
            subset.erase( subset.begin() + subset.size()-1 );
        }
    }
    
    
    
    vector<vector<int>> subsetsWithDup(vector<int> &nums) {
        // write your code here
        
        vector<int> subset;
        
        if( nums.size() == 0 )
        {
            ans.emplace_back(subset);
            return ans;
        }
        
        sort(nums.begin(), nums.end());
        
        dfs( 0, nums, subset );
        
        return ans;

        
    }
};

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值