491.非递减子序列
在这段代码中,start和used都有去重的作用,但他们的机制和目的不太一样。
start是为了防止纵向一直选择同一个元素,比如说数组为[1,2,3],有start控制迭代起点可以避免出现[1,1,1]的情况。
used是横向去重,记录当前递归层级中已经使用过的值。如果在同一层级中遇到相同的值,就直接跳过,避免生成重复的子序列。例如数组为[1,2,2],如果没有used,会重复生成两个[1,2]
class Solution:
def __init__(self):
self.track=[]
self.path=[]
def findSubsequences(self, nums: List[int]) -> List[List[int]]:
if len(nums)==0:
return self.res
self.backtrack(0,nums)
return self.path
def backtrack(self,start,nums):
if len(self.track)>=2:
self.path.append(self.track.copy())
used=set() #哈希集合防止重复选择相同元素
for i in range(start,len(nums)):
if self.track and self.track[-1]>nums[i]:
continue
if nums[i] in used:
continue
used.add(nums[i])
self.track.append(nums[i])
self.backtrack(i+1,nums)
self.track.pop()
46.全排列
class Solution:
def __init__(self):
self.track=[]
self.path=[]
def permute(self, nums: List[int]) -> List[List[int]]:
used=[False]*len(nums)
self.backtrack(nums,used)
return self.path
def backtrack(self,nums,used):
if len(nums)==len(self.track):
self.path.append(self.track.copy())
return
for i in range(len(nums)):
if used[i]:
continue
self.track.append(nums[i])
used[i]=True
self.backtrack(nums,used)
self.track.pop()
used[i]=False
"""
排列问题需要一个used数组,来判断是否使用过某个数字
不用剪枝,不需要写start
"""
47.全排列Ⅱ
去重一定要对元素进行排序,这样我们才方便通过相邻的节点来判断是否重复使用了。
class Solution:
def __init__(self):
self.track=[]
self.path=[]
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
nums.sort()
used=[False]*len(nums)
self.backtrack(nums,used)
return self.path
def backtrack(self,nums,used):
if len(nums)==len(self.track):
self.path.append(self.track.copy())
return
for i in range(len(nums)):
if (i>0 and nums[i]==nums[i-1] and used[i-1]==True) or used[i]:
continue
self.track.append(nums[i])
used[i]=True
self.backtrack(nums,used)
self.track.pop()
used[i]=False