LeetCode – Combination Sum II (Java)

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:
1) All numbers (including target) will be positive integers.
2) Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
3) The solution set must not contain duplicate combinations.

Java Solution

This problem is an extension of Combination Sum. The difference is one number in the array can only be used ONCE.

public List<List<Integer>> combinationSum2(int[] candidates, int target) {
    List<List<Integer>> result = new ArrayList<List<Integer>>();
    List<Integer> curr = new ArrayList<Integer>();
    Arrays.sort(candidates);
    helper(result, curr, 0, target, candidates);
    return result;
}
 
public void helper(List<List<Integer>> result, List<Integer> curr, int start, int target, int[] candidates){
    if(target==0){
        result.add(new ArrayList<Integer>(curr));
        return;
    }
    if(target<0){
        return;
    }
 
    int prev=-1;
    for(int i=start; i<candidates.length; i++){
        if(prev!=candidates[i]){ // each time start from different element
            curr.add(candidates[i]);
            helper(result, curr, i+1, target-candidates[i], candidates); // and use next element only
            curr.remove(curr.size()-1);
            prev=candidates[i];
        }
    }
}

2 thoughts on “LeetCode – Combination Sum II (Java)”

  1. We can literally use the same solution from Combination Sum I with just two slight modifications. One in the helper recursive call with i+1 and the other when sum==target to check if the list exists in result or not.

    class Solution {
    public List<List> combinationSum2(int[] candidates, int target) {
    List<List> result = new ArrayList();
    List temp = new ArrayList();
    Arrays.sort(candidates);
    helper(candidates,0,target,0,temp,result);
    return result;
    }

    private void helper(int[] candidates, int start, int target, int sum, List list, List<List> result){
    if(sum > target){
    return;
    }

    if(sum == target){
    Iterator i = result.iterator();
    int flag=0;
    while(i.hasNext()){
    if(list.equals(i.next())){
    flag=1;
    }
    }

    if(flag==0)
    result.add(new ArrayList(list));
    return;
    }

    else{
    for(int i=start;i<candidates.length;i++){
    list.add(candidates[i]);
    helper(candidates,i+1,target,sum+candidates[i],list,result);
    list.remove(list.size()-1);
    }
    }
    }
    }

  2. Another variation

    public class Solution {
    public IList<IList> CombinationSum2(int[] candidates, int target)
    {

    if (candidates == null || candidates.Length == 0)
    return null;

    var result = new List<IList>();
    List temp = new List();

    Array.Sort(candidates);

    DFS(candidates, target, 0, result, temp, 0);

    return result;
    }

    public void DFS(int[] candidates, int target, int startIndex, List<IList> results, List temp, int sum)
    {
    if (sum > target)
    return;

    if (sum == target)
    {
    List tempResult = new List(temp);
    results.Add(tempResult);
    return;
    }

    for (int i = startIndex; i < candidates.Length; i++)
    {
    temp.Add(candidates[i]);
    sum += candidates[i];
    DFS(candidates, target, i+1, results, temp, sum);
    while (i + 1 < candidates.Length && candidates[i] == candidates[i + 1])
    {
    i++;
    }
    sum -= candidates[i];
    temp.Remove(candidates[i]);
    }
    }
    }

Leave a Comment