递归算法(三)- 回溯法Backtracking

回溯法

回溯法Backtracking(找所有的可能)递归:

  1. 类似枚举,一层一层向下递归,尝试搜索答案。
  2. 找到答案: => 返回答案,并尝试别的可能
  3. 未找到答案: => 返回上一层递归,尝试别的可能
实战

给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。

解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。
在这里插入图片描述

注意:在设计算法时,要谨记我们之前所说的递归四要素:

  1. 接收的参数
  2. 返回值
  3. 终止条件
  4. 递归拆解:如何递归下一层
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        # 扩展法
        # [ ]
        # [1]
        # [2] [1,2]
        # [3] [1,3] [2,3] [1,2,3]
        # res = []
        # res.append([])
        # for num in nums:
        #     temp = [] # 用于存储扩展后的若干子集
        #     for i in res:
        #         r = list(i) # 相当于copy,避免引用传递
        #         r.append(num)
        #         temp.append(r)
        #     for r in temp:
        #         res.append(r)
        # return res


        # 方法二:回溯法:[1,2,3] 子集长度介于0--3
        # Time Complexity:O(N*2^N)
        # Space Complexity:O(N*2^N)
        # 长度
        #   0   [ ]
        #   1   [1] [2] [3]
        #   2   [1,2] [1,3] [2,3]
        #   3   [1,2,3]

        result = [[]]
        # 因为等于0 的长度(空集)已经加进去了
        for i in range(1,len(nums)+1): 
            self.backtracking(nums,result,i,0,[])
        return result

    def backtracking(self,nums,result,lenght,index,subset):
        # 终止条件:子集的长度 == 要找的长度
        if len(subset) == lenght:
            temp = list(subset) # 相当于copy,避免引用传递 list(subset)  等价于 subset[:]
            result.append(temp)
            return

        # 循环部分
        for i in range(index,len(nums)):
            subset.append(nums[i])
            self.backtracking(nums,result,lenght,i+1,subset)
            subset.pop() # 当backtracking出来一定要把新加入的元素删除掉

        # 方法三 DFS 
        # Time Complexity:O(N*2^N)
        # Space Complexity:O(N*2^N)
    #     result = []
    #     self.dfs(nums,result,0,[])
    #     return result

    # def dfs(self,nums,result,index,subset):
    #     result.append(subset[:])
    #     # 终止条件
    #     if index == len(nums):
    #         return 
    #     for i in range(index,len(nums)):
    #         subset.append(nums[i])
    #         self.dfs(nums,result,i+1,subset)
    #         subset.pop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

现实、狠残酷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值