LeetCode 刷题记录 78. Subsets

题目:
Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: nums = [1,2,3]
Output:
[
[3],
[1],
[2],
[1,2,3],
[1,3],
[2,3],
[1,2],
[]
]
解法1:
回溯法
c++:
与平常的回溯法相比,直接没有判断条件,直接加入path,且没有return语句

res.push_back(path);

nums = [1,2,3]
在这里插入图片描述

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> path;
        DFS(nums, path, res, 0);
        return res;
    }
    void DFS(vector<int>& nums, vector<int>& path,vector<vector<int>>& res,int start){
        
        
        res.push_back(path);
        
        
        for(int i = start; i < nums.size(); ++i){
            path.push_back(nums[i]);
            DFS(nums, path, res, i+1);
            path.pop_back();
        }
        
    }
};

java;

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
      List<List<Integer>>  res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        
        DFS(nums, path, res, 0);
        return res;

    }
    private void DFS(int[] nums, List<Integer> path,List<List<Integer>> res,int start){
        
       
        
        res.add(new ArrayList<>(path));
       
        for(int i = start; i < nums.length ; ++i){
            path.add(nums[i]);
            DFS(nums, path, res, i+1);
            path.remove(path.size() - 1);
        }
        
    }
}

python:

class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        self.DFS(nums, [], res, 0)
        return res
    def DFS(self, nums, path, res,start):
        
        
        res.append(path)
            
        for i in xrange(start, len(nums)):
           
            self.DFS(nums, path + [nums[i]], res, i+1)

解法2:
回溯法变体
对每一个元素都有选择或者不选择,不选择则不添加,所有的元素都加完即得到结果

					    []        
                   /          \        
                  /            \     
                 /              \
              [1]                []
           /       \           /    \
          /         \         /      \        
       [1 2]       [1]       [2]     []
      /     \     /   \     /   \    / \
  [1 2 3] [1 2] [1 3] [1] [2 3] [2] [3] []

图来自:[LeetCode] 78. Subsets 子集合

c++:

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        vector<int> path;
        DFS(nums, path, res, 0);
        return res;
    }
    void DFS(vector<int>& nums, vector<int>& path,vector<vector<int>>& res,int start){
        
        if(start == nums.size()){
            res.push_back(path);
            return;
        }
        
        
        
        DFS(nums, path, res, start+1);
        path.push_back(nums[start]);
        DFS(nums, path, res, start+1);
        path.pop_back();
        
        
    }
};

java:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
      List<List<Integer>>  res = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        
        DFS(nums, path, res, 0);
        return res;

    }
    private void DFS(int[] nums, List<Integer> path,List<List<Integer>> res,int start){
        
       
        if(start == nums.length){
            res.add(new ArrayList<>(path));
            return;
        }
        
        
        
        DFS(nums, path, res, start+1);
        path.add(nums[start]);
        DFS(nums, path, res, start+1);
        path.remove(path.size() - 1);
       
        
    }
}

python:

class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        self.DFS(nums, [], res, 0)
        return res
    def DFS(self, nums, path, res,start):
        
        if start == len(nums):
            res.append(path)
            return
        
        
        
        
        
        
            
        
        self.DFS(nums, path, res, start+1)
        self.DFS(nums, path + [nums[start]], res, start+1)

解法3:
迭代法
初始化首先为空集合,然后每一次复制结果中的元素,然后再原有的集合中加入新元素
在这里插入图片描述
c++:

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res = {{}};
        for(int num : nums){
            int size = res.size();
            for(int i = 0; i < size; i++){
                res.push_back(res[i]);
                res.back().push_back(num);
            }
        }
        return res;
    }
    
};

java:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>>  res = new ArrayList<>();
        res.add(new ArrayList<>());
        for(int num : nums){
            int size = res.size();
            for(int i = 0; i < size; i++){
                res.add(new ArrayList<>(res.get(i)));
                res.get(res.size()-1).add(num);
            }
        }
        return res;

    }
   
}

python:

class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = [[]]
        for num in nums:
            res += [ r + [num] for r in res]
        return res
    

解法4:
二进制法
nums = [1,2,3] 总共有23种组合 正好对应0-7 8个数字
8个数字的二进制形式分别对应一种集合如下图所示

在这里插入图片描述
图来自:[LeetCode] 78. Subsets 子集合
c++:

class Solution {
public:
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<vector<int>> res;
        int size = 1 << nums.size();
        for(int i = 0; i < size; i++){
            vector<int> path = convertIntToSet(nums,i);
            res.push_back(path);
        }
        
        return res;
    }
    vector<int> convertIntToSet(vector<int>& nums,int k){
        vector<int> sub;
        int idx = 0;
        for(int i = k; i > 0; i >>= 1){
            if(i & 1 == 1){
                sub.push_back(nums[idx]);
                //cout << nums[idx] << endl;
            }
            idx++;
        }
        return sub;
    }
};

java:

class Solution {
    public List<List<Integer>> subsets(int[] nums) {
        List<List<Integer>> res = new ArrayList<>();
        int size = 1 << nums.length;
        for(int i = 0; i < size; i++){
            List<Integer> path = convertIntToSet(nums,i);
            res.add(path);
        }
        
        return res;
    }
    List<Integer> convertIntToSet(int[] nums,int k){
        List<Integer> sub = new ArrayList<>();
        int idx = 0;
        for(int i = k; i > 0; i >>= 1){
            if((i & 1) == 1){
                sub.add(nums[idx]);
            }
            idx++;
        }
        return sub;
    }
}

python:

class Solution(object):
    def subsets(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        res = []
        #nums.sort()
        for i in xrange(1<<len(nums)):
            tmp = []
            j = 0
            while i > 0:
                
                if i & 1:  
                    tmp.append(nums[j])
                j += 1
                i >>= 1
            res.append(tmp)
           # print res
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值