491. 递增子序列
回溯+使用set去重
class Solution:
def findSubsequences(self, nums: List[int]) -> List[List[int]]:
res = []
path = []
def _backtracking(start_index, nums):
nonlocal res
nonlocal path
if len(path) >= 2:
res.append(path[:])
usage_list = set()
for i in range(start_index, len(nums)):
# not increasing subsequence or already used in this level
if path and nums[i] < path[-1] or nums[i] in usage_list:
continue
path.append(nums[i])
usage_list.add(nums[i])
_backtracking(i+1, nums)
path.pop()
_backtracking(0, nums)
return res
46. 全排列
回溯
- 如果num已经在path中,我们不取这个num
- 每层都是从0开始搜索而不是startIndex
- 需要used数组记录path里都放了哪些元素了
class Solution:
def permute(self, nums: List[int]) -> List[List[int]]:
res = []
path = []
def _backtracking(nums):
nonlocal res
nonlocal path
if len(path) == len(nums):
res.append(path[:])
return
for num in nums:
if num in path:
continue
path.append(num)
_backtracking(nums)
path.pop()
_backtracking(nums)
return res
47. 全排列 II
回溯+使用set和counter去重
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
res = []
path = []
count = Counter(nums)
def _backtracking(nums):
nonlocal res
nonlocal path
nonlocal count
if len(path) == len(nums):
res.append(path[:])
return
used_set = set()
for num in nums:
if count[num] == 0 or num in used_set:
continue
used_set.add(num)
count[num] -= 1
path.append(num)
_backtracking(nums)
count[num] += 1
path.pop()
_backtracking(nums)
return res
回溯+使用排序去重
-
还要强调的是去重一定要对元素进行排序,这样我们才方便通过相邻的节点来判断是否重复使用了。
-
如果要对树层中前一位去重,就用
used[i - 1] == false(前一位已经完成了回溯) -
如果要对树枝前一位去重用
used[i - 1] == true(前一位没有完成回溯) -
对于排列问题,树层上去重和树枝上去重,都是可以的,但是树层上去重效率更高!
class Solution:
def permuteUnique(self, nums: List[int]) -> List[List[int]]:
# res用来存放结果
if not nums: return []
res = []
used = [0] * len(nums)
def backtracking(nums, used, path):
# 终止条件
if len(path) == len(nums):
res.append(path.copy())
return
for i in range(len(nums)):
if not used[i]:
if i > 0 and nums[i] == nums[i-1] and not used[i-1]:
continue
used[i] = 1
path.append(nums[i])
backtracking(nums, used, path)
path.pop()
used[i] = 0
# 记得给nums排序
backtracking(sorted(nums),used,[])
return res