Description:
Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.
The same repeated number may be chosen from candidates unlimited number of times.
Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
Solution:
用map储存的dynamic programming
转移方程思想:
i, j 表示的是Integer,AnswerList(i) 表示所有的key为 i 的解集
AnswerList(j) = AnswerList(j - i) + AnswerList(i)
在下面代码中表示:如果key对应的map为空,则返回新建的ArrayList,如果非空,则返回key对应的map值。
sums.computeIfAbsent(candidates[i], (key) -> new ArrayList<>()).add(Arrays.asList(candidates[i]));
表示返回key对应的map,如果为空,则返回Collections.emptyList()
sums.getOrDefault(target, Collections.emptyList());
思路有点抽象,最好自己手动debug一遍(带入数据一步一步走下去)
总的来说:
- 遍历candidates数组,逐个插入,比如2,直接插入2。比如6,插入6之前,已经存在2 2 2 和3 3的list,在后面插入6.
- 获取前一步的结果 (sums.get[j - candidates[i]), 在前一步的结果中插入candidates[i] 。比如candidates[i] = 3, j = 5; 则伪代码等价如下思路
//伪代码
map.put(j , map.get(j - candidates[i]) + candidates[i])
//具体的来写就是
for(int j = candidates[i] + 1; j <= target; j++) {
List<List<Integer>> sumsSoFar = sums.computeIfAbsent(j - candidates[i], (key) -> new ArrayList<>());
for(List<Integer> sum : sumsSoFar) {
List<Integer> n = new ArrayList<>(sum);
n.add(candidates[i]);
sums.computeIfAbsent(j, (key) -> new ArrayList<>()).add(n);
}
}
- 这样一步一步走完,就把各种答案都组合起来了,具体map中值的变化可以debug看看。
综合代码如下:
public List<List<Integer>> combinationSum(int[] candidates, int target) {
Map<Integer, List<List<Integer>>> sums = new HashMap<>();
for(int i = 0; i < candidates.length; ++i) {
sums.computeIfAbsent(candidates[i], (key) -> new ArrayList<>()).add(Arrays.asList(candidates[i]));
for(int j = candidates[i] + 1; j <= target; j++) {
List<List<Integer>> sumsSoFar = sums.computeIfAbsent(j - candidates[i], (key) -> new ArrayList<>());
for(List<Integer> sum : sumsSoFar) {
List<Integer> n = new ArrayList<>(sum);
n.add(candidates[i]);
sums.computeIfAbsent(j, (key) -> new ArrayList<>()).add(n);
}
}
}
return sums.getOrDefault(target, Collections.emptyList());
}