LC491.递增子序列:
class Solution:
def __init__(self):
self.path = []
self.res = []
def findSubsequences(self, nums: List[int]) -> List[List[int]]:
self.backtracking(nums, 0)
return self.res
def backtracking(self, nums:List[int], startindex: int):
if len(self.path) >= 2: #如果path长度大于2才记录
self.res.append(self.path[:])
used_list = set() #定义一个set来判断是否有重复元素
for i in range(startindex, len(nums)):
#若当前元素值小于前一个时(非递增)或者曾用过,跳入下一循环
if self.path and nums[i] < self.path[-1] or nums[i] in used_list:
continue
used_list.add(nums[i]) #遍历过的元素加入set中
self.path.append(nums[i])
self.backtracking(nums, i+1)
self.path.pop() #回溯
首先要确定终止条件,当path大于2时,才记录!然后要创建一个新set来记录是否有重复元素出现,如果当前元素小于path最右边元素 或 曾经使用过该元素,则直接跳过。
LC46.全排列
class Solution:
def __init__(self):
self.path = []
self.res = []
def permute(self, nums: List[int]) -> List[List[int]]:
self.backtracking(nums)
return self.res
def backtracking(self, nums: List[int]):
if len(self.path) == len(nums): #返回全排列,当path长度等于nums长度时!
self.res.append(self.path[:])
return
for i in range(0, len(nums)): # 从头开始搜索
if nums[i] in self.path: # 若遇到self.path里已收录的元素,跳过
continue
self.path.append(nums[i])
self.backtracking(nums)
self.path.pop()
因为本题排列是有序的,这意味着同一层的元素可以重复使用,但同一树枝上不能重复使用 所以处理排列问题每层都需要从头搜索,故不再使用start_index
LC47.全排列 II
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
# res用来存放结果
if not nums: return []
res = []
used = [0] * len(nums)
def backtracking(nums, used, path):
# 终止条件
if len(path) == len(nums):
res.append(path.copy())
return
for i in range(len(nums)):
if not used[i]:
if i>0 and nums[i] == nums[i-1] and not used[i-1]:
continue
used[i] = 1
path.append(nums[i])
backtracking(nums, used, path)
path.pop()
used[i] = 0
# 记得给nums排序
backtracking(sorted(nums),used,[])
return res