491:递增子序列
例如:这道题乐乐自己做出来80%了,就差去重了:
总结一下去重的经验:
(1)如果能排序,那就用之前说的if i>0 and nums[i]==nums[i-1]:continue
(2)如果不能排序,那就借助set,dict或者是list数组进行去重。
这道题就是后者,但是乐乐今天刷这个题的时候,犯了个错以至于没有A出来,那就是set搞成全局变量了,那就很致命,这样就做成了“数组中不能用重复数字”的题型了。正解应该是每做一次递归,也就是每深入一层,就重新搞一个set,来记录数字是否被使用过,以达到,纵向可重复(递归),但是横向不能重复(for循环内)的目的。
具体代码如下:
class Solution:
def __init__(self):
self.res=[]
# self.s=set()
def traversal(self,nums,path,startIndex):
if len(path)>=2:
self.res.append(path[:])
if startIndex==len(nums):
return
s=set()
for i in range(startIndex,len(nums)):
if (path and nums[i]<path[-1]) or nums[i] in s:
continue
s.add(nums[i])
path.append(nums[i])
self.traversal(nums,path,i+1)
path.pop()
def findSubsequences(self,nums):
path=[]
self.traversal(nums,path,0)
return self.res
46:全排列
class Solution:
def permute(self,nums):
res=[]
path=[]
used=[False]*len(nums)
def Backtracking(used,nums):
if len(path)==len(nums):
res.append(path[:])
for i in range(len(nums)):
if used[i]==True:
continue
used[i]=True
path.append(nums[i])
Backtracking(used,nums)
path.pop()
used[i]=False
Backtracking(used,nums)
return res
定义一个used数组,记录每次用了哪些值,因为是全排列问题,所以就没有startindex,循环直接从0开始遍历,遍历到used数组用过了,就continue。很简单,三刷了,希望能记住。
47:全排列2
全排列2,题目的意思就是指不能有重复的,也就说不能重复的利用同一个值,也就是横向(层内)不能取相同索引的值,但是纵向可以。因为纵向如果取得相同的值也不是同一个索引的。这里要考虑如何层内去重,其实还是老方法,不过,在去重之前需要排序。
这题目也三刷了!
path=[]
res=[]
used=[False]*len(nums)
nums.sort()
def Backtracking(nums,used):
if len(path)==len(nums):
res.append(path[:])
for i in range(len(nums)):
if used[i]==True:
continue
if i>0 and nums[i]==nums[i-1] and used[i-1]==False:
continue
used[i]=True
path.append(nums[i])
Backtracking(nums,used)
path.pop()
used[i]=False
Backtracking(nums,used)
return res
主要是去重的部分:
if i>0 and nums[i]==nums[i-1] and used[i-1]==False:
continue
在去重的前提是,先把数组进行排序!然后在进行去重组合拳代码“i>0 and nums[i]==nums[i-1]
”,关键是这里还有一个used[i-1]==False
,这里的理解就是。used[i-1]==False,说明是数层上的去重!(好好理解这句话,是精髓!)