diff --git a/problems/0046.全排列.md b/problems/0046.全排列.md index 1e1252ae..5e36927c 100644 --- a/problems/0046.全排列.md +++ b/problems/0046.全排列.md @@ -211,44 +211,68 @@ class Solution { ``` Python: +**回溯** ```python3 class Solution: - def permute(self, nums: List[int]) -> List[List[int]]: - res = [] #存放符合条件结果的集合 - path = [] #用来存放符合条件的结果 - used = [] #用来存放已经用过的数字 - def backtrack(nums,used): - if len(path) == len(nums): - return res.append(path[:]) #此时说明找到了一组 - for i in range(0,len(nums)): - if nums[i] in used: - continue #used里已经收录的元素,直接跳过 - path.append(nums[i]) - used.append(nums[i]) - backtrack(nums,used) - used.pop() - path.pop() - backtrack(nums,used) - return res -``` + def __init__(self): + self.path = [] + self.paths = [] -Python(优化,不用used数组): + def permute(self, nums: List[int]) -> List[List[int]]: + ''' + 因为本题排列是有序的,这意味着同一层的元素可以重复使用,但同一树枝上不能重复使用(usage_list) + 所以处理排列问题每层都需要从头搜索,故不再使用start_index + ''' + usage_list = [False] * len(nums) + self.backtracking(nums, usage_list) + return self.paths + + def backtracking(self, nums: List[int], usage_list: List[bool]) -> None: + # Base Case本题求叶子节点 + if len(self.path) == len(nums): + self.paths.append(self.path[:]) + return + + # 单层递归逻辑 + for i in range(0, len(nums)): # 从头开始搜索 + # 若遇到self.path里已收录的元素,跳过 + if usage_list[i] == True: + continue + usage_list[i] = True + self.path.append(nums[i]) + self.backtracking(nums, usage_list) # 纵向传递使用信息,去重 + self.path.pop() + usage_list[i] = False +``` +**回溯+丢掉usage_list** ```python3 class Solution: + def __init__(self): + self.path = [] + self.paths = [] + def permute(self, nums: List[int]) -> List[List[int]]: - res = [] #存放符合条件结果的集合 - path = [] #用来存放符合条件的结果 - def backtrack(nums): - if len(path) == len(nums): - return res.append(path[:]) #此时说明找到了一组 - for i in range(0,len(nums)): - if nums[i] in path: #path里已经收录的元素,直接跳过 - continue - path.append(nums[i]) - backtrack(nums) #递归 - path.pop() #回溯 - backtrack(nums) - return res + ''' + 因为本题排列是有序的,这意味着同一层的元素可以重复使用,但同一树枝上不能重复使用 + 所以处理排列问题每层都需要从头搜索,故不再使用start_index + ''' + self.backtracking(nums) + return self.paths + + def backtracking(self, nums: List[int]) -> None: + # Base Case本题求叶子节点 + if len(self.path) == len(nums): + self.paths.append(self.path[:]) + return + + # 单层递归逻辑 + for i in range(0, len(nums)): # 从头开始搜索 + # 若遇到self.path里已收录的元素,跳过 + if nums[i] in self.path: + continue + self.path.append(nums[i]) + self.backtracking(nums) + self.path.pop() ``` Go: