给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
说明:
所有数字(包括 target)都是正整数。
解集不能包含重复的组合。
示例 1:
输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:
输入:candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
提示:
1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate 中的每个元素都是独一无二的。
1 <= target <= 500
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
每个数字允许使用多次
package algorithmtest;
import java.util.*;
public class combination_sum {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Set<List<Integer>> result = new HashSet<>();
ArrayList<Integer> curSelectList = new ArrayList<>();
dfs(candidates, target, result, curSelectList, 0, 0);
ArrayList<List<Integer>> ret = new ArrayList<>();
for (List<Integer> v : result) {
ret.add(v);
}
return ret;
}
public void checkSelect(int curTotal, int target, ArrayList<Integer> curSelectList, Set<List<Integer>> result) {
if (curTotal == target) {
curSelectList.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
result.add((List<Integer>) curSelectList.clone());
}
}
/**
* 每一步得到一个可以遍历的列表,然后循环遍历
*
* @param candidates
* @param target
* @param result
* @param curSelectList
* @param curTotal
* @param start
*/
public void dfs(final int[] candidates, final int target, Set<List<Integer>> result, ArrayList<Integer> curSelectList, int curTotal, int start) {
// 超过了目标 或者 已经遍历完了所有元素,则进入结算阶段
if (curTotal >= target) {
checkSelect(curTotal, target, curSelectList, result);
return;
}
// 得到当前能选择的值
ArrayList<Integer> canSelectValList = getCanSelect(candidates, target, curTotal);
if (canSelectValList.size() > 0) {
for (Integer v : canSelectValList) {
curSelectList.add(v);
curTotal += v;
dfs(candidates, target, result, curSelectList, curTotal, start);
curTotal -= v;
curSelectList.remove(v);
}
} else {
checkSelect(curTotal, target, curSelectList, result);
return;
}
}
public ArrayList<Integer> getCanSelect(final int[] candidates, final int target, int curTotal) {
ArrayList<Integer> list = new ArrayList<>();
for (Integer v : candidates) {
if (curTotal + v <= target) {
list.add(v);
}
}
return list;
}
public static void main(String[] args) {
int[] candidates = {7, 2, 3, 6};
int target = 7;
List<List<Integer>> lists = new combination_sum().combinationSum(candidates, target);
System.out.println(lists);
}
}
/*
[[2, 2, 3], [7]]
*/
每个数字只允许用1次
package algorithmtest;
import java.util.*;
public class combination_sum {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Set<List<Integer>> result = new HashSet<>();
ArrayList<Integer> curSelectList = new ArrayList<>();
dfs(candidates, target, result, curSelectList, 0, 0);
ArrayList<List<Integer>> ret = new ArrayList<>();
for (List<Integer> v : result) {
ret.add(v);
}
return ret;
}
/**
* 是否是子集
*
* @param intsSrc
* @param curSelectList
* @return
*/
public boolean isSub(ArrayList<Integer> intsSrc, ArrayList<Integer> curSelectList) {
ArrayList<Integer> ints = (ArrayList<Integer>) intsSrc.clone();
for (int i = curSelectList.size() - 1; i >= 0; i--) {
int v = curSelectList.get(i);
boolean isFind = false;
for (int j = 0; j < ints.size(); j++) {
if (ints.get(j) == v) {
ints.remove(j);
isFind = true;
break;
}
}
if (isFind == false) {
return false;
}
}
return true;
}
public void checkSelect(final int[] candidates, int curTotal, int target, ArrayList<Integer> curSelectList, Set<List<Integer>> result) {
if (curTotal == target) {
curSelectList.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
// int[]-->Integer[]
ArrayList<Integer> ints = new ArrayList<>();
for (int v : candidates) {
ints.add(v);
}
if (isSub(ints, curSelectList)) {
result.add((List<Integer>) curSelectList.clone());
}
}
}
/**
* 每一步得到一个可以遍历的列表,然后循环遍历
*
* @param candidates
* @param target
* @param result
* @param curSelectList
* @param curTotal
* @param start
*/
public void dfs(final int[] candidates, final int target, Set<List<Integer>> result, ArrayList<Integer> curSelectList, int curTotal, int start) {
// 超过了目标 或者 已经遍历完了所有元素,则进入结算阶段
if (curTotal >= target) {
checkSelect(candidates, curTotal, target, curSelectList, result);
return;
}
// 得到当前能选择的值
ArrayList<Integer> canSelectValList = getCanSelect(candidates, target, curTotal);
if (canSelectValList.size() > 0) {
for (Integer v : canSelectValList) {
curSelectList.add(v);
curTotal += v;
dfs(candidates, target, result, curSelectList, curTotal, start);
curTotal -= v;
curSelectList.remove(v);
}
} else {
checkSelect(candidates, curTotal, target, curSelectList, result);
return;
}
}
public ArrayList<Integer> getCanSelect(final int[] candidates, final int target, int curTotal) {
ArrayList<Integer> list = new ArrayList<>();
for (Integer v : candidates) {
if (curTotal + v <= target) {
list.add(v);
}
}
return list;
}
public static void main(String[] args) {
int[] candidates = {10, 1, 2, 7, 6, 1, 5};
int target = 8;
List<List<Integer>> lists = new combination_sum().combinationSum(candidates, target);
System.out.println(lists);
}
}
/*
[[1, 2, 5], [1, 1, 6], [2, 6], [1, 7]]
*/