Combination Sum II

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations incandidates where the candidate numbers sums totarget.

Each number incandidates may only be used once in the combination.

Note:

  • All numbers (includingtarget) will be positive integers.

  • The solution set must not contain duplicate combinations.

Example 1:

Input:
 candidates = 
[10,1,2,7,6,1,5]
, target = 
8
,

A solution set is:

[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]

Example 2:

Input:
 candidates = [2,5,2,1,2], target = 5,

A solution set is:

[
  [1,2,2],
  [5]
]

Analysis

Basically the same as Combination Sum, yet need to handle

1) duplicated elements

2) each element may only use once

Solution

Backtracking

基本和Combination Sum一样,但是(1)要处理重复元素的问题,并且(2)每个元素只能用一次

因此两点改变:

传入startIdx时,用i + 1,而不是i;

在每次循环结束后,如果有重复,则i++,跳过剩余的重复部分

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<>();

        Arrays.sort(candidates);
        comboHelper(target, 0, 0, candidates, new ArrayList<Integer>(), ans);

        return ans;
    }

    private void comboHelper(int target, int sum, int startIdx, int[] candidates, 
                            List<Integer> combo, List<List<Integer>> ans) {
        if (sum == target) {
            ans.add(new ArrayList<Integer>(combo));
            return;
        }

        if (sum > target) {
            return;
        }

        for (int i = startIdx; i < candidates.length; i++) {
            combo.add(candidates[i]);
            comboHelper(target, sum + candidates[i], i + 1, candidates, combo, ans);
            combo.remove(combo.size() - 1);
            while (i < candidates.length - 1 && candidates[i + 1] == candidates[i]) {
                i++;
            }
        }
    }
}

用remain而不是target,sum减少参数个数

class Solution {
    public List<List<Integer>> combinationSum2(int[] candidates, int target) {
        List<List<Integer>> ans = new ArrayList<>();

        Arrays.sort(candidates);
        comboHelper(target, 0, candidates, new ArrayList<Integer>(), ans);

        return ans;
    }

    private void comboHelper(int remain, int startIdx, int[] candidates, 
                            List<Integer> combo, List<List<Integer>> ans) {
        if (remain == 0) {
            ans.add(new ArrayList<Integer>(combo));
            return;
        }

        if (remain < 0) {
            return;
        }

        for (int i = startIdx; i < candidates.length; i++) {
            combo.add(candidates[i]);
            comboHelper(remain - candidates[i], i + 1, candidates, combo, ans);
            combo.remove(combo.size() - 1);
            while (i < candidates.length - 1 && candidates[i + 1] == candidates[i]) {
                i++;
            }
        }
    }
}

Last updated