题目:
Given a collection of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T.
Each number in C may only be used once in the combination.
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 10,1,2,7,6,1,5
and target 8
,
A solution set is:
[1, 7]
[1, 2, 5]
[2, 6]
[1, 1, 6]
这一题与上一题的区别在于C集合中的元素只能使用一次,而且C的元素可能会出现重复,因此,基本方法与上一题一致,先排序,再递归。只是在第二种情况(即求解不包含第一个元素的解时)数组应该跳到下一个不同的元素上。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class No39_CombinationSumII {
public static void main(String[] args){
System.out.println(combinationSum(new int[]{13,23,25,11,7,26,14,11,27,27,26,12,8,20,22,34,27,17,5,26,31,11,16,27,13,20,29,18,7,14,13,15,25,25,21,27,16,22,33,8,15,25,16,18,10,25,9,24,7,32,15,26,30,19}, 25));
}
public static List<List<Integer>> combinationSum(int[] candidates, int target) {
Arrays.sort(candidates);
List<List<Integer>> list = new ArrayList<List<Integer>>();
String s = "";
fun(candidates, target, 0, list, s);
return list;
}
public static void fun(int[] candidates, int target, int i, List<List<Integer>> list, String s){
if(target<0){
return;
}
if(target == 0){
List<Integer> element = new ArrayList<Integer>();
String[] sa = s.split(",");
for(int k=1;k<sa.length;k++){
element.add(Integer.valueOf(sa[k]));
}
list.add(element);
return;
}
if(i >= candidates.length)
return;
int j=0;
while(i+j<candidates.length && candidates[i+j] == candidates[i]) j++;
fun(candidates, target, i+j, list, s);
fun(candidates, target-candidates[i], i+1, list, s+","+candidates[i]);
}
}