题目:
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意: 解集不能包含重复的组合。
算法:
func combinationSum2(candidates []int, target int) [][]int {
ans := make([][]int, 0)
result := make([]int, 0)
cadidatasMap := make(map[int]int)
for i := range candidates {
cadidatasMap[candidates[i]] ++
}
cadidatasList := make([][]int, 0)
for num, cnt := range cadidatasMap {
cadidatasList = append(cadidatasList, []int{num, cnt, cnt})
}
var backtrack func(index, target int)
backtrack = func(index, target int){
if index >= len(cadidatasList) {
return
}
if target == 0 {
ans = append(ans, append([]int{}, result...))
return
}
// cadidatas[index]相同的数字选择0个,
// 为避免liine:39 backtrack重复进行选择0个cadidatas[index]的判断,去重
backtrack(index + 1, target)
// cadidatas[index]相同的数字选择[1,cadidatasList[index][1]]个
if target - cadidatasList[index][0] >= 0 && cadidatasList[index][1] > 0 {
result = append(result, cadidatasList[index][0])
cadidatasList[index][1] --
backtrack(index, target - cadidatasList[index][0])
result = result[:len(result) - 1]
cadidatasList[index][1] ++
}
}
backtrack(0, target)
return ans
}