题目描述:
给你一个 无重复元素 的整数数组 candidates
和一个目标整数 target
,找出 candidates
中可以使数字和为目标数 target
的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates
中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target
的不同组合数少于 150
个。
解题思路:
首先按照数组c的下标开始分析,对于目标数target,若当前index位置的元素t小于target,则t可以选取一次或者多次,为了避免重复,数组中相同元素只考虑一次,用一个临时列表list来存储当前组合的数字,为了能够遍历所有的可能性,再考虑下一个位置时,临时列表list需要讲当前index数字移除。
以上就是一个基本的回溯的思路。
代码实现:
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
Set<List<Integer>> s = new HashSet<>();
track(s, new ArrayList<>(), 0, candidates, target);
return new ArrayList<>(s);
}
private static void track(Set<List<Integer>> r, List<Integer> t, int s, int[] can, int target) {
if (target == 0) {
r.add(new ArrayList<>(t));
}
if (s >= can.length) {
return;
}
for (int i = s; i < can.length ; ++i) {
// 去重
if (i > s && can[i] == can[i - 1]) continue; // 当前path下,首元素相同的仅选取一次
if(can[i] > target) continue;
t.add(can[i]);
if (target > can[i]) {
track(r, t, i, can, target - can[i]);
}
track(r, t, i + 1, can, target - can[i]);
t.remove(t.size() - 1);
}
}