491.递增子序列 ,46.全排列 ,47.全排列 II

思路

终止条件,序列长度大于2。

去除重复元素:维护一个集合,集合包含当前for循环中使用过的数字,如果nums[i]出现过就跳过。

如果path为空或者满足递增序列条件:used添加该数字,path添加该数字

进入下一轮回溯

回溯中用到的变量,path存储当前的序列,i用于存储当前nums中的索引,在进入下一轮回溯时,使用当前数字的i+1

代码

class Solution:
    def findSubsequences(self, nums: List[int]) -> List[List[int]]:
        res=[]
        def backtrack(index,path):
            if len(path)>1:
                res.append(path[:])
            used=set()
            for i in range(index,len(nums)):
                if nums[i] in used:
                    continue 
                if not path or nums[i]>=path[-1]:
                    used.add(nums[i])
                    path.append(nums[i])
                    backtrack(i+1,path)
                    path.pop()
        backtrack(0,[])
        return res 

思路

终止条件:当path长度等于列表长度时,res添加path的copy,注意是拷贝,否则会存储相同的变量

由于全排列包含不同的数字,只需要遍历每个数字加上判断:当前数字不在path中,就可以添加,进入下一层循环。

只需要使用path一个变量

代码

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res=[]
        def backtrack(path):
            if len(path)==len(nums):
                res.append(path[:])
                return 
            for num in nums:
                if num not in path:
                    path.append(num)
                    backtrack(path)
                    path.pop()
        backtrack([])
        return res 

思路

包含了重复数字,需要去重,对于重复数字首先对数字排序,

使用一个used列表来对标记数字的使用

终止条件:同46,列表长度等于原始长度

遍历每个数字和他们的索引

如果当前数字使用过,或者上一位数字和当前数字相同但是没有使用,跳过循环

将当前数字加入path,进入下一轮

代码

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res=[]
        used=[False]*len(nums)
        def backtrack(path):
            if len(path)==len(nums):
                res.append(path[:])
                return 
            
            for i,num in enumerate(nums):
                if used[i] or (i>0 and nums[i]==nums[i-1] and not used[i-1]):
                    continue 
                used[i]=True 
                path.append(num)
                backtrack(path)
                path.pop()
                used[i]=False
        backtrack([])
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值