Update 0039.组合总和.md

This commit is contained in:
jianghongcheng
2023-05-26 10:28:01 -05:00
committed by GitHub
parent 847c60ac3c
commit 2c51420308

View File

@ -271,75 +271,101 @@ class Solution {
## Python ## Python
**回溯** 回溯(版本一)
```python ```python
class Solution: class Solution:
def __init__(self):
self.path = []
self.paths = []
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: def backtracking(self, candidates, target, total, startIndex, path, result):
''' if total > target:
因为本题没有组合数量限制所以只要元素总和大于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 return
if sum_ > target: if total == target:
result.append(path[:])
return return
# 单层递归逻辑 for i in range(startIndex, len(candidates)):
for i in range(start_index, len(candidates)): total += candidates[i]
sum_ += candidates[i] path.append(candidates[i])
self.path.append(candidates[i]) self.backtracking(candidates, target, total, i, path, result) # 不用i+1了表示可以重复读取当前的数
self.backtracking(candidates, target, sum_, i) # 因为无限制重复选取所以不是i+1 total -= candidates[i]
sum_ -= candidates[i] # 回溯 path.pop()
self.path.pop() # 回溯
def combinationSum(self, candidates, target):
result = []
self.backtracking(candidates, target, 0, 0, [], result)
return result
``` ```
**剪枝回溯** 回溯剪枝(版本一)
```python ```python
class Solution: class Solution:
def __init__(self):
self.path = []
self.paths = []
def backtracking(self, candidates, target, total, startIndex, path, result):
if total == target:
result.append(path[:])
return
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]]: def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
''' result =[]
因为本题没有组合数量限制所以只要元素总和大于target就算结束 self.backtracking(candidates, target, 0, [], result)
''' return result
self.path.clear() def backtracking(self, candidates, target, startIndex, path, result):
self.paths.clear() 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() candidates.sort()
self.backtracking(candidates, target, 0, 0) self.backtracking(candidates, target, 0, [], result)
return self.paths 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()
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 ## Go