题目
给定一个数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用一次。
说明:
- 所有数字(包括目标数)都是正整数。
- 解集不能包含重复的组合。
示例 1:
输入: candidates = [10,1,2,7,6,1,5], target = 8,
所求解集为:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5,
所求解集为:
[
[1,2,2],
[5]
]
思路:
背包问题,深度优先搜索(dfs)
代码
class Solution:
def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]:
self.ans = []
candidates = sorted(candidates)
def dfs(remain, t, path):
if t == 0:
self.ans.append(path)
return
if not remain or remain[0] > t:
return
head = remain[0]
dfs(remain[1:], t-head, path+[head])
i = 1
while i < len(remain) and remain[i] == remain[i-1]:
i += 1
dfs(remain[i:], t, path)
dfs(candidates, target, [])
return self.ans
import "sort"
func combinationSum2(candidates []int, target int) [][]int {
sort.Ints(candidates)
res := [][]int{}
sol := []int{}
backtrack(candidates, sol, target, &res)
return res
}
func backtrack(cand []int, sol []int, target int, res *[][]int) {
if target == 0 {
copySol := make([]int, len(sol))
copy(copySol, sol)
*res = append(*res, sol)
}
if len(cand) == 0 || cand[0] > target {
return
}
// sol = sol[:len(sol):len(sol)]
backtrack(cand[1:], append(sol, cand[0]), target-cand[0], res)
i := 1
for i < len(cand) && cand[i] == cand[i-1] {
i++
}
backtrack(cand[i:], sol, target, res)
}
网友评论