491.递增子序列[维持原序列顺序,同时保证递增】
回溯三部曲:
- backtrack( nums , startindex【一个元素不能重复使用】,path, res)
- 终止条件: 如果递归子序列>1,收集结果
- 单层遍历:
运用集合去重,不像之前先排序,然后用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里都有哪些元素使用了,一个排列里一个元素只能使用一次。
回溯三部曲:
- 回溯函数参数: backtrack(nums, path, used, res)
- 终止条件: 到达叶子节点,收集元素
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