代码随想录算法训练营第二十八天 | leetcode 491. 递增子序列,46.全排列,47.全排列 II
491. 递增子序列
题目:给定一个整型数组, 你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。
题目链接:491. 递增子序列
class Solution:
def __init__(self):
self.path = []
self.results = []
def findSubsequences(self, nums: List[int]) -> List[List[int]]:
self.backtracking(nums, 0)
return self.results
def backtracking(self, nums: List[int], start_index: int):
if len(self.path) >= 2:
self.results.append(self.path[:])
if start_index == len(nums):
return
usage_list = set()
for i in range(start_index, len(nums)):
if (self.path and nums[i] < self.path[-1]) or nums[i] in usage_list:
continue
usage_list.add(nums[i])
self.path.append(nums[i])
self.backtracking(nums, i + 1)
self.path.pop()
46.全排列
题目:给定一个 没有重复 数字的序列,返回其所有可能的全排列。
题目链接:46. 全排列
class Solution:
def __init__(self):
self.result = []
self.path = []
def permute(self, nums: List[int]) -> List[List[int]]:
'''
因为本题排列是有序的,这意味着同一层的元素可以重复使用,但同一树枝上不能重复使用
所以处理排列问题每层都需要从头搜索,故不再使用start_index
'''
self.backtracking(nums)
return self.result
def backtracking(self, nums: List[int]):
if len(self.path) == len(nums):
self.result.append(self.path[:])
return
for i in range(0, len(nums)):
if nums[i] in self.path: # 若遇到self.path里已收录的元素,跳过
continue
self.path.append(nums[i])
self.backtracking(nums)
self.path.pop()
47.全排列 II
题目:给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
题目链接:47. 全排列 II
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.sort()
backtracking(nums, used, [])
return res