216、组合总和II
基本思想:
回溯法
具体实现:
剪枝优化:
1.元素总和大于目标值,在递归终止的地方剪枝
2.和77题思路一样,for循环的范围剪枝
代码:
class Solution { List<List<Integer>> result = new ArrayList<>(); LinkedList<Integer> path = new LinkedList<>(); public List<List<Integer>> combinationSum3(int k, int n) { backTracking(n, k, 1, 0); return result; } private void backTracking(int targrtSum, int k, int startIndex, int sum){ if(sum > targrtSum){ return;//剪枝 } if (path.size() == k){ if (sum == targrtSum) { result.add(new ArrayList<>(path)); } return; } for (int i = startIndex; i <= 9 - (k - path.size()) + 1; i++){ path.add(i); sum += i; backTracking(targrtSum,k,i+1,sum); path.removeLast(); sum -= i; } } }
39、组合总和
具体实现:
代码:
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
result = []
track = []
Sum = 0
self.backtrack(candidates,target,0,result,track,Sum)
return result
def backtrack(self,candidates,target,start,result,track,Sum):
if Sum == target:
result.append(track[:])
return
if Sum > target:
return
for i in range(start,len(candidates)):
track.append(candidates[i])
Sum += candidates[i]
self.backtrack(candidates,target,i,result,track,Sum)
Sum -= candidates[i]
track.pop()
剪枝:
先对candidates进行从小到大的排序
如果下一层的sum,也就是本层的sum+candidates[i] >traget,就跳出循环
代码:
class Solution:
def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
result = []
track = []
Sum = 0
candidates.sort()
self.backtrack(candidates,target,0,result,track,Sum)
return result
def backtrack(self,candidates,target,start,result,track,Sum):
if Sum == target:
result.append(track[:])
return
i = start
while i < len(candidates):
if Sum + candidates[i] <= target:
track.append(candidates[i])
Sum += candidates[i]
self.backtrack(candidates,target,i,result,track,Sum)
Sum -= candidates[i]
track.pop()
i += 1
else:
break