mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-12 13:45:39 +08:00
Update 0039.组合总和.md
This commit is contained in:
@ -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
|
||||||
|
Reference in New Issue
Block a user