2024/5/9【回溯5/6】--代码随想录算法训练营day29|491.递增子序列、46.全排列、 47.全排列 II

491.递增子序列[维持原序列顺序,同时保证递增】

力扣链接
在这里插入图片描述

回溯三部曲:

  1. backtrack( nums , startindex【一个元素不能重复使用】,path, res)
  2. 终止条件: 如果递归子序列>1,收集结果
  3. 单层遍历:在这里插入图片描述
    运用集合去重,不像之前先排序,然后用used等去重
    集合.add(元素) | 栈顶 path[-1]
class Solution:
    def findSubsequences(self, nums):
        result = []
        path = []
        self.backtracking(nums, 0, path, result)
        return result
    
    def backtracking(self, nums, startIndex, path, result):
        if len(path) > 1:
            result.append(path[:])  # 注意要使用切片将当前路径的副本加入结果集
        if startIndex >= len(nums): return 
        
        uset = set()  # 使用集合对本层元素进行去重
        for i in range(startIndex, len(nums)):
            if (path and nums[i] < path[-1]) or nums[i] in uset:  ###!!!!请注意这一行
                continue
            
            uset.add(nums[i])  # 记录这个元素在本层用过了,本层后面不能再用了
            path.append(nums[i])
            self.backtracking(nums, i + 1, path, result)
            path.pop()

46.全排列

力扣链接
在这里插入图片描述

这里是引用
而used数组,其实就是记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次。
回溯三部曲:

  1. 回溯函数参数: backtrack(nums, path, used, res)
  2. 终止条件: 到达叶子节点,收集元素
    3.单层递归逻辑: 如果元素用过,就continue,遍历从0开始
class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        self.backtrack(nums, [], [False]*len(nums),res)
        return res

    def backtrack(self, nums, path ,used, res):
        if len(path) == len(nums):
            res.append(path[:])
            return 
        for i in range(0, len(nums)):
            if used[i]: 
                continue
            used[i] = True
            path.append(nums[i])
            self.backtrack(nums, path, used, res)
            path.pop()
            used[i] = False


47.全排列 II

力扣链接
在这里插入图片描述
使用used数组去重 ,排列在这里插入图片描述
要么用 nums.sort() ,要么用sorted(nums),排序

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        res = []
        self.backtrack(sorted(nums), [], [False]*len(nums),res)
        return res

    def backtrack(self, nums, path ,used, res):
        if len(path) == len(nums):
            res.append(path[:])
            return 
        for i in range(0, len(nums)):
          #如果nums[i]被用过  ,或者说   nums[i-1]=nums[i],两个同一树层
            if used[i] or ( i>0 and nums[i]==nums[i-1]  and used[i-1]==False): 
                continue
            used[i] = True
            path.append(nums[i])
            self.backtrack(nums, path, used, res)
            path.pop()
            used[i] = False
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值