DFS + backtraking
之前用的DP做,觉得similar as the dividing the coins problem
Combination I: 一个元素可以取多次(输入没有重复): Combination Sum
Given a set of… For example, given candidate set 2,3,6,7
and target 7
, A solution set is: [7]
,[2, 2, 3]
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
if (candidates == null || candidates.length == 0) {
return null;
}
Arrays.sort(candidates);
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
helper(candidates, target, res, path, 0);
return res;
}
public void helper(int[] candidates, int target, List<List<Integer>> res, List<Integer> path, int start){
if (target == 0) {
res.add(new ArrayList<Integer>(path));
return;
}
for (int i = start; i < candidates.length; i++) {
if (candidates[i] > target) {
break;
}
path.add(candidates[i]);
helper(candidates, target - candidates[i], res, path, i);
path.remove(path.size() -1);
}
}
}
DP解法
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
if (candidates == null || candidates.length == 0) {
return null;
}
//like a DP array
List<List<List<Integer>>> res = new ArrayList<>(target + 1);
Arrays.sort(candidates);
//initialize res
for (int i = 0; i <= target; i++) {
List<List<Integer>> out = new ArrayList<>();
if (i == 0) {
List<Integer> in = new ArrayList<>();
out.add(in);
}
res.add(out);
}
for (int i = 1; i <= target; i++) {
List<List<Integer>> outlist = new ArrayList<>();
for (int j = 0; j < candidates.length; j++) {
if (candidates[j] > i) {
continue;
}
List<List<Integer>> last = res.get(i - candidates[j]);
for (List<Integer> t : last) {
List<Integer> innerlist = new ArrayList<>(t);
if (innerlist.size() > 0
&& t.get(innerlist.size() - 1) > candidates[j]) {
continue;
}
innerlist.add(candidates[j]);
outlist.add(innerlist);
}
}
res.set(i, outlist);
}
//if there is no match, it should return [], rather than [[]]
return res.get(target);
}
}
Combination2: Given a collection of…且一个元素只能取一次 ->输入可能有重复,输出不重复
//list all的题,dfs + backtracking
public class Solution {
public List<List<Integer>> combinationSum2(int[] num, int target) {
List<List<Integer>> res = new ArrayList<>();
if (num == null) return res;
Arrays.sort(num);
List<Integer> l = new ArrayList<>();
helper(res, l, num, target, 0);
return res;
}
public void helper(List<List<Integer>> res, List<Integer> path, int[] num, int target, int start) {
if (target == 0){
res.add(new ArrayList<Integer>(path));
return;
}
for (int i = start; i < num.length; i++) {
if (num[i] > target) {
break;
}
if (i > start && num[i] == num[i-1]) {
continue;
}
path.add(num[i]);
helper(res, path, num, target - num[i], i+1);
path.remove(path.size()-1);
}
}
}