491.递增子序列
题目描述: 491.递增子序列.
解法
回溯
class Solution(object):
def backtrack(self,start,path):
if len(path) > 1:
self.res.append(path[:])
uset = set()
for i in range(start,self.length):
if len(path)>0 and self.nums[i] < path[-1]:
continue
if self.nums[i] in uset:
continue
uset.add(self.nums[i])
path.append(self.nums[i])
self.backtrack(i+1,path)
path.pop()
def findSubsequences(self, nums):
self.nums = nums
self.length = len(nums)
self.res = []
self.backtrack(0,[])
return self.res
使用set是去重的又一种方法,由于原序列不可以进行排序,所以不能用num[i] == num[i-1]这样的方式去重,因此使用set集合,查看当前的i是否在set中
set一般只有一个使用方法,就是原序列的顺序不可以发生改变,需要按照原序列的顺序输出。
使用set时一定要注意,在每一层的回溯上初始化一个set
46.全排列
题目描述: 46.全排列.
解法
回溯
class Solution(object):
def backtrack(self,path):
if len(path) == len(self.nums):
self.res.append(path[:])
return
for i in range(len(self.nums)):
if self.used[i]:
continue
path.append(self.nums[i])
self.used[i] = True
self.backtrack(path)
path.pop()
self.used[i] = False
def permute(self, nums):
self.used=[False] * len(nums)
self.nums = nums
self.res = []
self.backtrack([])
return self.res
在每一层的排列中,都会需要遍历所有的元素,并且还没有固定的顺序,那么这个时候就需要用一个整体的used,对应元素的索引位置的used设为bool值,并且这个used也要加入到回溯中。
注意这个used和放在每一层used的区别。
47.全排列 II
题目描述: 47.全排列 II.
解法
回溯
class Solution(object):
def backtrack(self,path):
if len(path) == self.length:
self.res.append(path[:])
for i in range(self.length):
if self.used[i] or (i > 0 and self.nums[i] == self.nums[i-1] and self.used[i-1] == False):
continue
self.used[i] = True
path.append(self.nums[i])
self.backtrack(path)
self.used[i] = False
path.pop()
def permuteUnique(self, nums):
self.length = len(nums)
self.used = [False] * self.length
self.nums = nums
self.nums.sort()
self.res = []
self.backtrack([])
return self.res
这里面比较关键的问题是
1.如何判定这个元素是否使用过
2.如何考虑重复的元素
首先问题1是否使用过,可以直接用used,这个主要是为了考虑在每一层的回溯中,需要遍历哪些内容。
而问题2,需要进行去重,所以是需要考虑重复的元素该怎么办,一般情况是先将数组进行排列,然后使用set或者num[i]==num[i-1]
但是单独使用num[i]==num[i-1]会去掉过多的内容,这是为什么呢,因为这个题是会在每一层遍历之前遍历过的元素,那么就要在同一层或者是同一向下的回溯进行。常规的num[i]==num[i-1]会将所有会出现的重复都删掉。那么这时候就需要借助used数组,判断上一个元素是False的话,那就是在同一层进行去重,判断上一个元素是True的话,就是在同一分支进行去重。
这里还是存在着不少疑问
1.num[i]==num[i-1]和set是否是完全等价的
2.num[i]==num[i-1]是否是树层去重
3.如果是树层去重,为什么还需要used数组辅助