From 2c514203087e51aa244ca3df18108e44d64f3f89 Mon Sep 17 00:00:00 2001 From: jianghongcheng <35664721+jianghongcheng@users.noreply.github.com> Date: Fri, 26 May 2023 10:28:01 -0500 Subject: [PATCH] =?UTF-8?q?Update=200039.=E7=BB=84=E5=90=88=E6=80=BB?= =?UTF-8?q?=E5=92=8C.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0039.组合总和.md | 136 ++++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 55 deletions(-) diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index c4ee5ca6..b6034755 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -271,75 +271,101 @@ class Solution { ## Python -**回溯** +回溯(版本一) ```python class Solution: - def __init__(self): - self.path = [] - self.paths = [] - def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: - ''' - 因为本题没有组合数量限制,所以只要元素总和大于target就算结束 - ''' - self.path.clear() - self.paths.clear() - self.backtracking(candidates, target, 0, 0) - return self.paths - - def backtracking(self, candidates: List[int], target: int, sum_: int, start_index: int) -> None: - # Base Case - if sum_ == target: - self.paths.append(self.path[:]) # 因为是shallow copy,所以不能直接传入self.path + def backtracking(self, candidates, target, total, startIndex, path, result): + if total > target: return - if sum_ > target: + if total == target: + result.append(path[:]) return - # 单层递归逻辑 - for i in range(start_index, len(candidates)): - sum_ += candidates[i] - self.path.append(candidates[i]) - self.backtracking(candidates, target, sum_, i) # 因为无限制重复选取,所以不是i+1 - sum_ -= candidates[i] # 回溯 - self.path.pop() # 回溯 + for i in range(startIndex, len(candidates)): + total += candidates[i] + path.append(candidates[i]) + self.backtracking(candidates, target, total, i, path, result) # 不用i+1了,表示可以重复读取当前的数 + total -= candidates[i] + path.pop() + + def combinationSum(self, candidates, target): + result = [] + self.backtracking(candidates, target, 0, 0, [], result) + return result + ``` -**剪枝回溯** +回溯剪枝(版本一) ```python class Solution: - def __init__(self): - self.path = [] - self.paths = [] - def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: - ''' - 因为本题没有组合数量限制,所以只要元素总和大于target就算结束 - ''' - self.path.clear() - self.paths.clear() - - # 为了剪枝需要提前进行排序 - candidates.sort() - self.backtracking(candidates, target, 0, 0) - return self.paths - - def backtracking(self, candidates: List[int], target: int, sum_: int, start_index: int) -> None: - # Base Case - if sum_ == target: - self.paths.append(self.path[:]) # 因为是shallow copy,所以不能直接传入self.path + def backtracking(self, candidates, target, total, startIndex, path, result): + if total == target: + result.append(path[:]) return - # 单层递归逻辑 - # 如果本层 sum + condidates[i] > target,就提前结束遍历,剪枝 - for i in range(start_index, len(candidates)): - if sum_ + candidates[i] > target: - return - sum_ += candidates[i] - self.path.append(candidates[i]) - self.backtracking(candidates, target, sum_, i) # 因为无限制重复选取,所以不是i-1 - sum_ -= candidates[i] # 回溯 - self.path.pop() # 回溯 + + for i in range(startIndex, len(candidates)): + if total + candidates[i] > target: + break + total += candidates[i] + path.append(candidates[i]) + self.backtracking(candidates, target, total, i, path, result) + total -= candidates[i] + path.pop() + + def combinationSum(self, candidates, target): + result = [] + candidates.sort() # 需要排序 + self.backtracking(candidates, target, 0, 0, [], result) + return result + +``` + +回溯(版本二) + +```python +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + result =[] + self.backtracking(candidates, target, 0, [], result) + return result + def backtracking(self, candidates, target, startIndex, path, result): + if target == 0: + result.append(path[:]) + return + if target < 0: + return + for i in range(startIndex, len(candidates)): + path.append(candidates[i]) + self.backtracking(candidates, target - candidates[i], i, path, result) + path.pop() + +``` + +回溯剪枝(版本二) + +```python +class Solution: + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: + result =[] + candidates.sort() + self.backtracking(candidates, target, 0, [], result) + return result + def backtracking(self, candidates, target, startIndex, path, result): + if target == 0: + result.append(path[:]) + return + + for i in range(startIndex, len(candidates)): + if target - candidates[i] < 0: + break + path.append(candidates[i]) + self.backtracking(candidates, target - candidates[i], i, path, result) + path.pop() + ``` ## Go