题目:
给定一个数组 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]
]
java:
public class Leetcode040 {
static LinkedList<Integer> path = new LinkedList<>();
static List<List<Integer>> ans = new LinkedList<>();
static boolean[] used;
static int sum = 0;
public static List<List<Integer>> combinationSum2(int[] candidates, int target) {
used = new boolean[candidates.length];
//加标志数组.用来判断是否使用过.
Arrays.fill(used, false);
//对数组进行排序.
Arrays.sort(candidates);
backTracking(candidates, target, 0);
return ans;
}
private static void backTracking(int[] candidates, int target, int startIndex) {
if (sum == target) {
ans.add(new ArrayList<>(path));
}
for (int i = startIndex; i < candidates.length; i++) {
if (sum + candidates[i] > target) {
break;
}
//出现重复节点.同层的第一个节点已经被访问过.直接跳过.
if (i > 0 && candidates[i] == candidates[i - 1] && !used[i - 1]) {
continue;
}
used[i] = true;
sum += candidates[i];
path.add(candidates[i]);
//每个节点选择一次.
backTracking(candidates, target, i + 1);
used[i] = false;
sum -= candidates[i];
path.removeLast();
}
}
public static void main(String[] args) {
int[] candidates = {10, 1, 2, 7, 6, 1, 5};
List<List<Integer>> sum2 = combinationSum2(candidates, 8);
System.out.println(sum2);
}
}
Go:
package LeetCode
import "sort"
var (
res40 [][]int
path40 []int
used []bool
)
func CombinationSum2(nums []int, target int) [][]int {
res40, path40 = make([][]int, 0), make([]int, 0, len(nums))
used = make([]bool, len(nums))
sort.Ints(nums)
dfs40(nums, target, 0)
return res40
}
func dfs40(nums []int, target int, startIndex int) {
//target不断减小.为0说明达到了目标值.
if target == 0 {
tmp := make([]int, len(path40))
copy(tmp, path40)
res40 = append(res40, tmp)
return
}
for i := startIndex; i < len(nums); i++ {
if nums[i] > target {
break
}
//说明前面元素已经使用过了.不满足条件.
if i > 0 && nums[i] == nums[i-1] && used[i-1] == false {
continue
}
path40 = append(path40, nums[i])
used[i] = true
dfs40(nums, target-nums[i], i+1)
used[i] = false
path40 = path40[:len(path40)-1]
}
}
func main() {
nums := []int{10, 1, 2, 7, 6, 1, 5}
sum2 := LeetCode.CombinationSum2(nums, 7)
fmt.Println(sum2)
}
消失的人回不去的青春.
如果大家喜欢我的分享的话.可以关注我的微信公众号
念何架构之路