问题
Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
The same repeated number may be chosen from C unlimited number of times.
Note:
All numbers (including target) will be positive integers.
Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
The solution set must not contain duplicate combinations.
For example, given candidate set 2,3,6,7 and target 7,
A solution set is:
[7]
[2, 2, 3]*
思路
由于每个元素可以用多次,针对某个组合来说(以【2,2,3】为例)
1. 首先选中2,那么target还剩下5。第二次还可以选2,3 ,但是不能选6,因为6已经超过target了。迭代重复这个过程。可以选出【2,2,3】。
2. 再次重复这个过程,第一次选3,然后target剩下4,剩下的就不可以选了。
Code
public class Solution {
public List<List<Integer>> combinationSum(int[] candidates, int target) {
List<List<Integer>> result = new ArrayList<List<Integer>>();
if(candidates == null || target < 0){
return result;
}
Arrays.sort(candidates);
helper(candidates, target, result , new ArrayList<Integer>() , 0);
return result;
}
private void helper(int[] candidates, int target, List<List<Integer>> result, List<Integer> solution , int begin){
if(target == 0){
result.add(new ArrayList<Integer>(solution));
return;
}
for(int i = begin ; i < candidates.length && target >= candidates[i] ; i++){
solution.add(candidates[i]);
helper(candidates, target-candidates[i] , result , solution , i);
solution.remove(solution.size() - 1);
}
}
}
附加ArrayList的remove方法解析
ArrayList的remove方法有两个重载版本。分别是
public E remove(int);
public boolean remove(Object);
第一个方法是删除指定位置的元素,第二个方法是删除与参数equal的首次出现的元素。那么问题来了,如果List的定义为:
List<Integer> mList = new ArrayList<Integer>();
那到底是删除指定位置的元素还是删除与参数相等的数字呢?
这个要看重载的规律:
参数类型加宽(类型相容) > 自动装箱 > 变长参数
所以,如果mList中的元素有[1,2,3,4,5]
,我们调用方法:
mList.remove(1)
结果变为[1,3,4,5]
。
再调用mList.remove(new Integer(1))
mList中的元素最终为[3,4,5]
。