491.递增子序列
这道题要求不能有相同的递增子序列,子集+去重,但是又要求是递增的子序列,所以不能对这个给定的集合进行排序,因此不能用之前题目中的去重逻辑
class Solution(object):
def findSubsequences(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
self.backtracking(nums, 0, res, [])
return res
def backtracking(self, nums, startindex, res, path):
# 集合中无元素剩余时终止,相当于遍历完了,所以可以不写
if len(path) > 1: # 要求递增子序列中至少两个元素
res.append(path[:])
uset = set() # 每一层中,遇到重复的就要去掉,用set来去重,每一层遍历完之后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])
self.backtracking(nums, i+1, res, path)
path.pop()
46.全排列
全排列问题中[1, 2]和[2, 1]算两个集合,因此不需要用startindex了,每次都从0开始选择没被选择的元素。所以排列问题需要一个used数组,标记已经选择的元素。
class Solution(object):
def permute(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
res = []
used = [False]*len(nums)
self.backtracking(nums, used, res, [])
return res
def backtracking(self, nums, used, res, path):
if len(path) == len(nums):
res.append(path[:])
return
for i in range(0, len(nums)):
if used[i] == True: # 遇到被选择过的就跳过
continue
path.append(nums[i])
used[i] = True
self.backtracking(nums, used, res, path)
used[i] = False
path.pop()
47.全排列 II
这题中包含重复数字,因此是去重+全排列
class Solution(object):
def permuteUnique(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
nums.sort()
res = []
used = [False]*len(nums)
self.backtracking(nums, [], res, used)
return res
def backtracking(self, nums, path, res, 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 used[i-1] == False) or used[i] == True:
continue # 这边改为used[i-1] == True也可以,True是在树枝上去重,而False是对树层去重,树枝去重更麻烦
path.append(nums[i])
used[i] = True
self.backtracking(nums, path, res, used)
used[i] = False
path.pop()