leetcode-编程-回溯算法

回溯算法思路解析

# 回溯算法框架
result = []
def backtrack(路径, 选择列表):
    if 满足结束条件:
        result.add(路径)
        return

    for 选择 in 选择列表:
        做选择
        backtrack(路径, 选择列表)
        撤销选择

回溯类题目汇总

题型一:排列、组合、子集相关问题

剑指 Offer 38. 字符串的排列

题目
回溯法题解

# 回溯法见评论
class Solution:
    def permutation(self, s: str) -> List[str]:
        self.res=[]
        def backtrack(s,path):
            if not s:
                self.res.append(path)
            seen=set()  #对子序列去重操作
            for i in range(len(s)):
                if s[i] in seen:continue 
                seen.add(s[i])
                backtrack(s[:i]+s[i+1:], path+s[i])
        backtrack(s, '')
        return self.res 

46. 全排列–类似上面38题

在这里插入图片描述

题目
题解

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        self.res=[]
        def backtrack(s,path):
            if not s:
                return self.res.append(path)
            # seen=set() #把所有的注释取消也是对的
            for i in range(len(s)):
                # if s[i] in seen :continue   
                # seen.add(s[i])
                backtrack(s[:i]+s[i+1:], path+[s[i]])
        backtrack(nums, [])
        return self.res

47. 全排列 II

题目
在这里插入图片描述

class Solution:
    def permuteUnique(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        n=len(nums)
        res=[]
        def backtrack(s,path):
            if not s and path not in res:
                res.append(path)
            for i in range(len(s)):
                backtrack(s[:i]+s[i+1:],path+[s[i]])
        backtrack(nums,[])
        return res 

39. 组合总和

题目
题解
在这里插入图片描述

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        candidates.sort()
        n=len(candidates)
        res=[]
        def backtrack(i,tmp_sum,tmp):
            if tmp_sum>target or i==n:
                return  
            if tmp_sum==target:
                return res.append(tmp)
            for j in range(i,n):
                if tmp_sum+candidates[j]>target:
                    break   
                backtrack(j,tmp_sum+candidates[j],tmp+[candidates[j]])
        backtrack(0,0,[])
        return res   

40. 组合总和 II

题目
题解
在这里插入图片描述

# 推荐
class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        if not candidates:
            return []
        candidates.sort()
        n = len(candidates)
        res = []
        
        def backtrack(i, tmp_sum, tmp_list):
            if tmp_sum == target:
                res.append(tmp_list)
                return 
            for j in range(i, n):
                if tmp_sum + candidates[j]  > target : break
                if j > i and candidates[j] == candidates[j-1]:continue
                backtrack(j + 1, tmp_sum + candidates[j], tmp_list + [candidates[j]])
        backtrack(0, 0, [])    
        return res
class Solution:
    def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
        def dfs(begin,path,residue):
            if residue==0:
                res.append(path[:])
                return  
            for i in range(begin,n):
                if candidates[i]>residue:
                    break 
                if i>begin and candidates[i-1]==candidates[i]:
                    continue 
                path.append(candidates[i])
                dfs(i+1,path,residue-candidates[i])
                path.pop()
        n=len(candidates)
        if n==0:return []
        candidates.sort()
        res=[]
        dfs(0,[],target)
        return res  

78. 子集

题目
题解-带整理同类型题目
在这里插入图片描述

# 回溯
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = []
        n = len(nums)
        
        def helper(i, tmp):
            res.append(tmp)
            for j in range(i, n):
                helper(j + 1,tmp + [nums[j]] )
        helper(0, [])
        return res  

Python itertools模块combinations方法:添加链接描述

# 库函数
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = []
        for i in range(len(nums)+1):
            for tmp in itertools.combinations(nums, i):
                res.append(tmp)
        return res

90. 子集 II

题目

# 法一
class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        n=len(nums)
        res=[]
        def backtrack(i,tmp):
            res.append(tmp)
            for j in range(i,n):
                if j>i and nums[j]==nums[j-1]:continue
                backtrack(j+1,tmp+[nums[j]])
        backtrack(0,[])
        return res 
# 法二
class Solution:
    def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        n=len(nums)
        res=[]
        def backtrack(i,tmp):
            if tmp not in res:
                res.append(tmp)
            for j in range(i,n):
                backtrack(j+1,tmp+[nums[j]])
        backtrack(0,[])
        return res 

77. 组合

在这里插入图片描述
题目
题解

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        def backtrack(nums, tmp):
            if not nums:
                res.append(tmp)
                return 
            for i in range(len(nums)):
                backtrack(nums[:i] + nums[i+1:], tmp + [nums[i]])
        backtrack(nums, [])
        return res

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值