491.递增子序列 46.全排列 47.全排列 II
491.递增子序列
1、在递归函数里建立一个集合,用来存放每层使用过的数字,防止产生重复的子数组。遍历每层时,集合需要清空。
class Solution:
def findSubsequences(self, nums: List[int]) -> List[List[int]]:
result = []
path = []
def backtracking(nums, startIndex):
if len(path) >= 2:
result.append(path[:])
if len(nums) == startIndex:
return
used_set = set()
for i in range(startIndex, len(nums)):
if path and path[-1] > nums[i] or nums[i] in used_set:
continue
used_set.add(nums[i])
path.append(nums[i])
backtracking(nums, i+1)
path.pop()
return
backtracking(nums, 0)
return result
46.全排列
排列问题的不同:
1、每层都是从0开始搜索而不是startIndex
2、需要used数组记录path里都放了哪些元素了
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
result = []
path = []
used = [False] * len(nums)
def backtracking(nums):
if len(path) == len(nums):
result.append(path[:])
return
for i in range(0, len(nums)):
if used[i] == True:
continue
used[i] = True
path.append(nums[i])
backtracking(nums)
used[i] = False
path.pop()
return
backtracking(nums)
return result
47.全排列 II
1、去重一定要对元素进行排序,这样才方便通过相邻的节点来判断是否重复使用了
2、对同一树层,前一位(也就是nums[i-1])如果使用过,那么就进行去重。
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
result = []
path = []
used = [False] * len(nums)
def backtracking(nums):
if len(nums) == len(path):
result.append(path[:])
return
for i in range(0, len(nums)):
if used[i] == True or (i > 0 and nums[i-1] == nums[i] and used[i-1] == False):
continue
used[i] = True
path.append(nums[i])
backtracking(nums)
used[i] = False
path.pop()
return
nums.sort()
backtracking(nums)
return result