diff --git a/problems/0491.递增子序列.md b/problems/0491.递增子序列.md index 436dbf01..56a70e8b 100644 --- a/problems/0491.递增子序列.md +++ b/problems/0491.递增子序列.md @@ -267,79 +267,53 @@ class Solution { ### Python python3 -**回溯** +回溯 利用set去重 ```python class Solution: - def __init__(self): - self.paths = [] - self.path = [] + def findSubsequences(self, nums): + result = [] + self.backtracking(nums, 0, [], result) + return result - def findSubsequences(self, nums: List[int]) -> List[List[int]]: - ''' - 本题求自增子序列,所以不能改变原数组顺序 - ''' - self.backtracking(nums, 0) - return self.paths - - def backtracking(self, nums: List[int], start_index: int): - # 收集结果,同78.子集,仍要置于终止条件之前 - if len(self.path) >= 2: - # 本题要求所有的节点 - self.paths.append(self.path[:]) + def backtracking(self, nums, startIndex, path, result): + if len(path) > 1: + result.append(path[:]) # 将当前路径的副本加入结果集 - # Base Case(可忽略) - if start_index == len(nums): - return + used = set() # 使用集合来进行去重操作 + for i in range(startIndex, len(nums)): + if path and nums[i] < path[-1]: + continue # 如果当前元素小于上一个元素,则跳过当前元素 + + if nums[i] in used: + continue # 如果当前元素已经使用过,则跳过当前元素 + + used.add(nums[i]) # 标记当前元素已经使用过 + self.backtracking(nums, i + 1, path + [nums[i]], result) - # 单层递归逻辑 - # 深度遍历中每一层都会有一个全新的usage_list用于记录本层元素是否重复使用 - 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() ``` -**回溯+哈希表去重** +回溯 利用哈希表去重 ```python class Solution: - def __init__(self): - self.paths = [] - self.path = [] + def findSubsequences(self, nums): + result = [] + path = [] + self.backtracking(nums, 0, path, result) + return result - def findSubsequences(self, nums: List[int]) -> List[List[int]]: - ''' - 本题求自增子序列,所以不能改变原数组顺序 - ''' - self.backtracking(nums, 0) - return self.paths - - def backtracking(self, nums: List[int], start_index: int): - # 收集结果,同78.子集,仍要置于终止条件之前 - if len(self.path) >= 2: - # 本题要求所有的节点 - self.paths.append(self.path[:]) + def backtracking(self, nums, startIndex, path, result): + if len(path) > 1: + result.append(path[:]) # 注意要使用切片将当前路径的副本加入结果集 - # Base Case(可忽略) - if start_index == len(nums): - return + used = [0] * 201 # 使用数组来进行去重操作,题目说数值范围[-100, 100] + for i in range(startIndex, len(nums)): + if (path and nums[i] < path[-1]) or used[nums[i] + 100] == 1: + continue # 如果当前元素小于上一个元素,或者已经使用过当前元素,则跳过当前元素 + + used[nums[i] + 100] = 1 # 标记当前元素已经使用过 + path.append(nums[i]) # 将当前元素加入当前递增子序列 + self.backtracking(nums, i + 1, path, result) + path.pop() - # 单层递归逻辑 - # 深度遍历中每一层都会有一个全新的usage_list用于记录本层元素是否重复使用 - usage_list = [False] * 201 # 使用列表去重,题中取值范围[-100, 100] - # 同层横向遍历 - for i in range(start_index, len(nums)): - # 若当前元素值小于前一个时(非递增)或者曾用过,跳入下一循环 - if (self.path and nums[i] < self.path[-1]) or usage_list[nums[i]+100] == True: - continue - usage_list[nums[i]+100] = True - self.path.append(nums[i]) - self.backtracking(nums, i+1) - self.path.pop() ``` ### Go