package test1;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*Input: candidates = [2,3,6,7], target = 7,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
可以把这道题转化为背包问题,以以下的表格为例,行可以代表作将要装进背包内物品的重量,列表示背包一共可以装多少物品,从左往右,从上往下依次计算累加。
*/
/* 1 2 3 4 5 6 7
*
2 0 2 0 4(2,2) 0 6 0
3 0 2 3 4 5 6 7
6 0 2 3 4 5 6 7
7
*/
public class CombinationSum {
public static void main(String[] args) {
List<List<Integer>> combinationSum = combinationSum(new int[] { 2, 3, 6, 7 }, 8);
System.out.println(combinationSum);
}
public static List<List<Integer>> combinationSum(int[] candidates,int target) {
Arrays.sort(candidates);
int[][] result = new int[candidates.length][target + 1];
Map<Integer, List<List<Integer>>> resuMap = new HashMap<>();
for (int i = 0; i < result.length; i++) {
for (int j = 1; j <= target; j++) {
if (j - candidates[i] < 0) {
continue;
}
List<List<Integer>> list2 = null;
if (resuMap.get(j) == null) {
list2 = new ArrayList<>();
} else {
list2 = resuMap.get(j);
}
if (j % candidates[i] == 0) {
// 可以整除的情况
result[i][j] = j;
List<Integer> list1 = new ArrayList<>();
for (int k = 0; k < j / candidates[i]; k++) {
list1.add(candidates[i]);
}
list2.add(list1);
}
if (i == 0) {
if (resuMap.get(j) == null) {
result[i][j] = 0;
}
} else {
int can = candidates[i];
result[i][j] = Math.max(result[i - 1][j], result[i - 1][j
- candidates[i]]
+ candidates[i]);
if (resuMap.get(j - candidates[i]) != null) {
for (List<Integer> resultList : resuMap.get(j - candidates[i])) {
List<Integer> list = new ArrayList<>();
list.addAll(resultList);
list.add(can);
if (!list2.contains(list)) {
list2.add(list);
}
}
}
}
resuMap.put(j, list2);
}
}
List<List<Integer>> list = new ArrayList<List<Integer>>();
return resuMap.get(target) == null ? list : resuMap.get(target);
}
}