首页 > 其他 > 详细

面试题 08.04. 幂集

时间:2020-04-03 23:48:17      阅读:74      评论:0      收藏:0      [点我收藏+]

题目:

幂集。编写一种方法,返回某集合的所有子集。集合中不包含重复的元素。

说明:解集不能包含重复的子集。

示例:

输入: nums = [1,2,3]
输出:
[
[3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]

解答:

对于每个数字,可取可不取。对于这一点:cur.push_back(nums[i]);dfs(nums,i+1,res,cur);cur.pop_back();就可以保证每个数字要么取,要么不取。

但对于[1,1,1]这样的序列:

当我们取了第一个1:后面两个1的情况可能是零个1、一个1或者两个1,后面的情况先不需要考虑。这样组合起来一共是:[1]、[1,1]、[1,1,1]。

接下来再不取这第一个1的时候,后面两个1的情况还可能为零个1、一个1或两个1。这样组合起来是:[1]、[1,1]。

可以看到有两个子集:[1]、[1,1]重复了。

现在回头看一下我们取第一个1的情况:得到的结果:[1]、[1,1]、[1,1,1]。这实际正好是我们所需要的全部可能子集。

所以对于对第二个1进行dfs以及第三个1进行dfs时就可以直接跳过。(注意不是for循环中遍历到第二个1、第三个1时跳过,而是dfs(xxx,第二个1,xxx)和dfs(xxx,第三个1,xxx)的时候跳过)

对于相同的数字我们需要合并处理,所以处理前要从小到大排序。

当然实际这道题规定了集合中没有重复数字,简单的取/不取,循环即可。

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<int>cur;
        vector<vector<int>> res;
        dfs(nums,0,res,cur);
        return res;
    }
    void dfs(const vector<int>& nums,int cur_pos,vector<vector<int>>& res,vector<int>& cur){
        res.push_back(cur);
        for(int i=cur_pos;i<nums.size();++i){
            if(i>cur_pos and nums[i]==nums[i-1]){
                continue;
            }
            cur.push_back(nums[i]);
            dfs(nums,i+1,res,cur);
            cur.pop_back();
        }
    }
};

技术分享图片

 

面试题 08.04. 幂集

原文:https://www.cnblogs.com/FdWzy/p/12629694.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!