给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。

    candidates 中的每个数字在每个组合中只能使用 一次 。

    注意:解集不能包含重复的组合。

    示例 1:

    输入: candidates = [10,1,2,7,6,1,5], target = 8,
    输出:
    [
    [1,1,6],
    [1,2,5],
    [1,7],
    [2,6]
    ]
    示例 2:

    输入: candidates = [2,5,2,1,2], target = 5,
    输出:
    [
    [1,2,2],
    [5]
    ]

    提示:

    1 <= candidates.length <= 100
    1 <= candidates[i] <= 50
    1 <= target <= 30


    1. class Solution {
    2. public List<List<Integer>> combinationSum2(int[] candidates, int target) {
    3. List<List<Integer>> res = new ArrayList<>();
    4. Arrays.sort(candidates); //排序剪枝
    5. dfs(candidates, 0, target, new ArrayList<Integer>(), res);
    6. return res;
    7. }
    8. private void dfs(int[] candidates, int idx, int target, List<Integer> path, List<List<Integer>> res) {
    9. if (target == 0) {
    10. res.add(new ArrayList(path));
    11. return;
    12. }
    13. for (int i = idx; i < candidates.length; ++i) {
    14. //剪枝
    15. if (target - candidates[i] < 0) break;
    16. //去重
    17. if (i > idx && candidates[i] == candidates[i-1]) continue;
    18. path.add(candidates[i]);
    19. dfs(candidates, i+1, target-candidates[i], path, res);
    20. path.remove(path.size()-1);
    21. }
    22. }
    23. }