491.递增子序列
因为同一父节点下的同层上使用过的元素不能再使用
class Solution:
def findSubsequences(self, nums: List[int]) -> List[List[int]]:
def backtrack(startindex,path):
if len(path)>1:
res.append(path[:]) # 注意要使用切片将当前路径的副本加入结果集
# 注意这里不要加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])
backtrack(i+1,path)
path.pop()
res=[]
backtrack(0,[])
return res
46.全排列
used数组是记录此时path里都有哪些元素使用了,一个排列里一个元素只能使用一次。
排列问题:
- 每层都是从0开始搜索而不是startIndex
- 需要used数组记录path里都放了哪些元素了
树枝上去重(used[i - 1] == true)的树型结构如下:
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
def backtracking(used,path):
if len(path)==len(nums):
res.append(path[:])
return
for i in range(len(nums)):
if used[i]:
continue
used[i]=True
path.append(nums[i])
backtracking(used,path)
path.pop()
used[i]=False
res=[]
backtracking([False] * len(nums),[])
return res
47.全排列 I
返回的是所有不重复的全排列
对于排列问题,树层上去重和树枝上去重,都是可以的,但是树层上去重效率更高!
树层上去重(used[i - 1] == false),的树形结构如下:
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
nums.sort()
def backtrack(path,used):
if len(path)==len(nums):
res.append(path[:])
return
for i in range(0,len(nums)):
if i > 0 and nums[i] == nums[i - 1] and not used[i - 1]:
continue
if used[i]==True:
continue
used[i]=True
path.append(nums[i])
backtrack(path,used)
path.pop()
used[i]=False
res=[]
backtrack([],[False]*len(nums))
return res