40 - combined sum (II)

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];
        }


    }
}

Tags: Python Algorithm leetcode

Posted on Fri, 15 Oct 2021 01:58:07 -0400 by mustatin