LC491 递增子序列
给你一个整数数组 nums
,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案
思路:难点在去重,需要用used数组。另外,used是函数内部的局部(临时)变量,每次用完会释放,所以递归时调用函数里面的used数组的改变,不会影响外层的used。可以print(id(used))看一下,它们的地址是不一样的。
class Solution:
def findSubsequences(self, nums: List[int]) -> List[List[int]]:
path, paths = [], []
def backtracking(start_index):
if len(path) > 1:
paths.append(path[:])
if start_index == len(nums):
return
used = [False] * 201
for i in range(start_index, len(nums)):
if used[nums[i]]:
continue
if not path or (path and nums[i] >= path[-1]):
path.append(nums[i])
used[nums[i]] = True
backtracking(i+1)
path.pop()
else:
continue
backtracking(0)
return paths
LC46 全排列
给定一个不含重复数字的数组 nums
,返回其 所有可能的全排列 。
思路:排列问题每次从头遍历到尾,之前没有用过的数可以往里加。所以也不需要start_index作为起始。
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
path, paths = [], []
used = [False] * 21
def backtracking():
if len(path) == len(nums):
paths.append(path[:])
return
for i in range(len(nums)):
if used[nums[i]] == True:
continue
path.append(nums[i])
used[nums[i]] = True
backtracking()
path.pop()
used[nums[i]] = False
backtracking()
return paths
LC47 排列2
给定一个可包含重复数字的序列 nums
,按任意顺序 返回所有不重复的全排列。
思路:树层上去重,used[i-1] = False时剪枝(如图,used是从上一层递归下来的),注意理解一下剪枝的逻辑。
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
nums.sort()
path, paths = [], []
used = [False] * len(nums)
def backtracking():
if len(path) == len(nums):
paths.append(path[:])
return
for i in range(len(nums)):
if used[i] == True:
continue
if i > 0 and used[i-1] == False and nums[i] == nums[i-1]: # cut
continue
path.append(nums[i])
used[i] = True
backtracking()
path.pop()
used[i] = False
backtracking()
return paths