这里的回溯直接用的labuladong的算法框架,回溯解释
1、全排列
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def dfs(nums,temp):
if len(temp) == len(nums):
res.append(temp[:])
for i in range(len(nums)):
if nums[i] in temp:
continue
temp.append(nums[i])
dfs(nums,temp)
temp.pop()
res = []
if not nums:
return res
dfs(nums,[])
return res
2、全排列 II
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
def dfs(nums,temp,visited):
if len(nums)==len(temp):
res.append(temp[:])
for i in range(len(nums)):[1,1',1'']
if not visited[i]:#当前的节点没被选中,假如为1'
if i>0 and nums[i]==nums[i-1] and not visited[i-1]:# 1和1'相同,而且刚才回溯完 1 的visited变成了False,所以这种就要剪枝
continue
visited[i] = True
temp.append(nums[i])
dfs(nums,temp,visited)
visited[i] = False
temp.pop()
visited = [False]*len(nums)
res = []
nums.sort()
if not nums:
return res
dfs(nums,[],visited)
return res
3、组合总和
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
res = []
def recur(pos,candidates,target,temp):
if target==sum(list(temp)):
res.append(temp[:])
# return
for i in range(pos,len(candidates)):
if sum(list(temp))>target:
break
temp.append(candidates[i])
recur(i,candidates,target,temp)
temp.pop()
if not candidates:
return res
candidates.sort()
recur(0,candidates,target,[])
return res
4、组合总和 II
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
candidates.sort()
if len(candidates)==0:
return []
res = []
temp = []
self.recur(0,temp,candidates,target,res)
return res
def recur(self,position,temp,candidates,target,res):
if target==0:
res.append(temp[:])
for cur in range(position,len(candidates)):
if cur>position and candidates[cur-1]==candidates[cur]:#cur>position
#表示去除当前层的重复元素,如第二个实例,如果只写candidates[cur-1]==candidates[cur],这样会把[1,2,2]这个组合也去掉了
continue
if target<candidates[cur]:
break
temp.append(candidates[cur])
self.recur(cur+1,temp,candidates,target-candidates[cur],res)
temp.pop()
5、字符串的排列
这道题和全排列II是一样的
class Solution:
def permutation(self, s: str) -> List[str]:
if len(s)<1:
return []
res = []
def recur(s,temp,visited):
if len(temp) == len(s):
res.append(''.join(temp))
return
for i in range(len(s)):
if visited[i]:
continue
if i>0 and not visited[i-1] and s[i]==s[i-1]:
continue
temp.append(s[i])
visited[i] = True
recur(s,temp,visited)
temp.pop()
visited[i] = False
s = list(s)
s.sort()
visited = [False] * len(s)
recur(s,[],visited)
return res
6、子集
class Solution:
def subsets(self, nums: List[int]) -> List[List[int]]:
res = []
if len(nums)==0:
return res
def recur(position,temp):
res.append(temp)
for i in range(position,len(nums)):
recur(i+1,temp+[nums[i]])
recur(0,[])
return res
7、子集 II
class Solution:
def subsetsWithDup(self, nums: List[int]) -> List[List[int]]:
res = []
if len(nums)==0:
return res
def recur(position,temp):
res.append(temp)
for i in range(position,len(nums)):
if i>position and nums[i]==nums[i-1]:
continue
recur(i+1,temp+[nums[i]])
nums.sort()
recur(0,[])
return res