subject
Given an array of candidates and a target number target, find out all combinations in candidates that can make the sum of numbers target.
Each number in candidates can only be used once in each combination.
Note: the solution set cannot contain duplicate combinations.
Example 1:
input: candidates = [10,1,2,7,6,1,5], target = 8, output: [ [1,1,6], [1,2,5], [1,7], [2,6] ]
Example 2:
input: candidates = [2,5,2,1,2], target = 5, output: [ [1,2,2], [5] ]
thinking
Characteristics of this topic
1. candidates does not indicate that the element is not heavy, so the element is repeated
2. Elements in candidates cannot be selected repeatedly. Each combination can only be used once
3. path combination unique
De emphasis (difficulty)
1. The collection has duplicate elements and cannot have duplicate combinations
2. In the search process, we should remove the repeated combination, that is, the used elements cannot be selected repeatedly
"Used" has two dimensions in this tree structure. One dimension is used on the same branch (vertical) and the other dimension is used on the same tree layer (horizontal).
3. The same branch is an element in a combination, so we don't need to duplicate it (the same is also because the set has the same element). What we want to duplicate is the "used" on the same tree layer, excluding repeated combinations
4. If the tree layer is de duplicated, the array needs to be sorted

trilogy
parameter
1. path, res (global variable)
2. candidates and target given by the title
3. sum records the elements and of the combined path
4. Take the combination startIndex in a collection (collection elements cannot be reused, lower level recursive startIndex==i+1)
5. bool type array used, used to record whether the elements on the same branch have been used
Single layer recursive abort condition
1. Sum > target return (can be omitted after cutting)
2,sum==target res.add(path)
Each layer traverses the processing node logic
duplicate removal
To remove the weight is "used on the same tree layer" (horizontal)

When candidates[i] == candidates[i - 1] are the same: (the set is sorted first, and the tree layer is good to remove duplication)
- used[i - 1] == true, indicating that the same tree branch candidates[i - 1] has been used
- used[i - 1] == false, indicating that the same tree layer candidates[i - 1] has been used, which is the case we want to exclude
Single layer traversal logic:
for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target; i++) { // used[i - 1] == true, indicating that the same tree branch candidates[i - 1] has been used // used[i - 1] == false, indicating that the same tree layer candidates[i - 1] has been used // To skip elements used in the same tree layer if (i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false) { continue; } path.push_back(candidates[i]); //to update sum += candidates[i]; used[i] = true; backtracking(candidates, target, sum, i + 1, used); // And 39. The difference between the sum of combinations 1: here is i+1, and each number can only be used once in each combination //Undo backtracking and update path.pop_back(); used[i] = false; sum -= candidates[i]; }
Shear branch
After sorting the total set, if the sum of the next layer (sum+candidates[i]) of this layer is greater than the target, the current cycle can be ended
for(int i=startIndex;i<candidates.length && (sum+candidates[i])<=target;i++)
code
class Solution { //global variable List<Integer> path = new ArrayList<>(); List<List<Integer>> res = new ArrayList<>(); public List<List<Integer>> combinationSum2(int[] candidates, int target) { //Remove the duplicate tree layer elements and sort the collection first Arrays.sort(candidates); dfs(candidates,target,0,0,new boolean[candidates.length]); return res; } public void dfs(int[] candidates,int target,int sum,int begin,boolean[]used){ //break condition if(sum == target){ res.add(new ArrayList<>(path)); return; } //ergodic for (int i=begin;i<candidates.length;i++){ //Pruning if((sum+candidates[i])>target)break; //De duplication tree layer repeat element if(i>0 && candidates[i]==candidates[i-1] && used[i-1]==false)continue; //Process nodes and update sum and used path.add(candidates[i]); sum+=candidates[i]; used[i]=true; //recursion dfs(candidates,target,sum,i+1,used); //Undo backtracking and update sum and used path.remove(path.size()-1); used[i]=false; sum-=candidates[i]; } } }