From 1c1b8cb84841780bef64f002a7cbc19dc52b697c Mon Sep 17 00:00:00 2001 From: Asterisk <44215173+casnz1601@users.noreply.github.com> Date: Sun, 10 Oct 2021 16:57:27 +0800 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 补充python代码和注释 --- problems/0039.组合总和.md | 80 ++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/problems/0039.组合总和.md b/problems/0039.组合总和.md index e6f65700..4470c79e 100644 --- a/problems/0039.组合总和.md +++ b/problems/0039.组合总和.md @@ -264,25 +264,73 @@ class Solution { } ``` -## Python +## Python +**回溯** ```python3 class Solution: + def __init__(self): + self.path = [] + self.paths = [] + def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: - res = [] - path = [] - def backtrack(candidates,target,sum,startIndex): - if sum > target: return - if sum == target: return res.append(path[:]) - for i in range(startIndex,len(candidates)): - if sum + candidates[i] >target: return #如果 sum + candidates[i] > target 就终止遍历 - sum += candidates[i] - path.append(candidates[i]) - backtrack(candidates,target,sum,i) #startIndex = i:表示可以重复读取当前的数 - sum -= candidates[i] #回溯 - path.pop() #回溯 - candidates = sorted(candidates) #需要排序 - backtrack(candidates,target,0,0) - return res + ''' + 因为本题没有组合数量限制,所以只要元素总和大于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 + return + if sum_ > target: + 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() # 回溯 +``` +**剪枝回溯** +```python3 +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 + 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() # 回溯 ``` ## Go