40. Combinaison Sum II (retour arrière + déduplication racine)

Étant donné un tableau de candidats et un nombre cible cible, découvrez toutes les combinaisons de candidats qui peuvent faire la somme des nombres cible.

Chaque numéro de candidats ne peut être utilisé qu'une seule fois dans chaque combinaison.

Description:

Tous les nombres (y compris le nombre cible) sont des entiers positifs.
L'ensemble de solutions ne peut pas contenir de combinaisons répétées.
Exemple 1:

Entrée: candidats = [10,1,2,7,6,1,5], cible = 8,
l'ensemble de solutions est:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

Analyse:

Par rapport aux autres combinaisons, la différence dans cette question est que le tableau d'origine contient des éléments répétés et qu'il ne peut y avoir de combinaisons répétées dans l'ensemble de solutions. La clé est de dédupliquer la racine de l'arborescence. Par exemple, les trois éléments d'un {1,1,2} peut être utilisé comme racine, mais a [0], a [1] et a [1], a [0] sont des doublons, donc en choisissant un [1] comme "racine" , il est nécessaire de déterminer si l'élément peut être utilisé comme "racine". Le tableau utilisé est introduit ici pour enregistrer l'utilisation de chaque élément.

Lorsque vous accédez à un nouvel élément qui peut être utilisé comme "racine", vérifiez d'abord si l'élément précédent est le même. S'il est le même, regardez le tableau utilisé. 若used[i - 1] == false 说明这两个节点在数结构的一层,都是等着被选做“根”的,是横着走过来的,如果used[i - 1] == true,则说明是一条树枝,是从上到下走过来的。Ce que nous devons faire pour supprimer les doublons est de faites un seul de ces éléments répétés. Les branches, ne permettent pas aux éléments répétés d'être à nouveau les racines de l'arbre, alors sautez lorsque vous rencontrez false, et laissez-les former une branche unique lors de la rencontre de true (combinaison)

class Solution {
    
    
public:
    vector<vector<int>> ret;
    vector<int> path;
    void backTracking(vector<int>& candidates, int target, int startIndex, vector<bool>& used){
    
    
        if(target == 0){
    
    
            ret.push_back(path);
            return;
        }
        if(target < 0){
    
    
            return;
        }
        for(int i = startIndex; i < candidates.size(); i++){
    
    
            // 去重的关键语句:
            // used[i - 1] == false 说明这两个节点在数结构的一层,都是等着被选做“根”的
            // 如果used[i - 1] == true,则说明是一条树枝,从上到下走过的
            // 我们要做到的去重就是让这些重复的元素只做出来一条树枝,不让重复的元素再次当树根
            // 所以遇到false就跳过,遇到true就让它们组成一条唯一的树枝(组合)
            if(i > 0 && candidates[i] == candidates[i - 1] && used[i - 1] == false){
    
    
                continue;
            }
            used[i] = true;
            target -= candidates[i];
            path.push_back(candidates[i]);
            backTracking(candidates, target, i + 1, used);
            used[i] = false;
            target += candidates[i];
            path.pop_back();
        }

    }
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
    
    
        // 初始化used数组
        vector<bool> used(candidates.size(), false);
        sort(candidates.begin(), candidates.end());
        backTracking(candidates, target, 0, used);
        return ret;
    }
};

Insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/qq_34612223/article/details/113920849
conseillé
Classement