力扣Leetcode 78 | 子集(Subsets)

参考:
https://leetcode-cn.com/problems/subsets/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–10/
https://leetcode-cn.com/problems/subsets/solution/hui-su-python-dai-ma-by-liweiwei1419/

1 迭代法

从条件上入手,先只考虑给定数组的 1 个元素的所有子数组,然后再考虑数组的 2 个元素的所有子数组 … 最后再考虑数组的 n 个元素的所有子数组。求 k 个元素的所有子数组,只需要在 k - 1 个元素的所有子数组里边加上 nums [ k ] 即可。

例如 nums [1 , 2, 3] 的遍历过程:
在这里插入图片描述
java代码:

public List<List<Integer>> subsets(int[] nums) {
    List<List<Integer>> ans = new ArrayList<>();
    ans.add(new ArrayList<>());//初始化空数组
    for(int i = 0;i<nums.length;i++){
        List<List<Integer>> ans_tmp = new ArrayList<>();
        //遍历之前的所有结果
        for(List<Integer> list : ans){
            List<Integer> tmp = new ArrayList<>(list);
            tmp.add(nums[i]); //加入新增数字
            ans_tmp.add(tmp);
        }
        ans.addAll(ans_tmp);
    }
    return ans;
}

python代码:

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res=[[]]
        for i in nums:
            l=len(res)
            for j in range(l):
                c=res[j].copy()
                c.append(i)
                res.append(c)
        return res
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = [[]]
        for i in nums:
            res = res + [[i] + num for num in res]
        return res

2 递归(回溯算法)

需要判断结果集是所有的节点还是所有的叶子节点。
另外,递归过程,也分为前序遍历和后序遍历,理解两者的区别。

理解递归的终止条件。
回溯搜索的问题,状态空间很大,能剪枝就尽量剪枝。

参考,讲解的特别好,特别是视频:

3 位运算

class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        size = len(nums)
        n = 1 << size
        res = []
        for i in range(n):
            cur = []
            for j in range(size):
                if i >> j & 1:
                    cur.append(nums[j])
            res.append(cur)
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值