40. Suma combinada II (retroceso + deduplicación raíz)

Dada una serie de candidatos y un objetivo de número objetivo, averigüe todas las combinaciones de candidatos que pueden hacer la suma de los números objetivo.

Cada número de candidatos solo se puede usar una vez en cada combinación.

Descripción:

Todos los números (incluido el número objetivo) son números enteros positivos.
El conjunto de soluciones no puede contener combinaciones repetidas.
Ejemplo 1:

Entrada: candidatos = [10,1,2,7,6,1,5], objetivo = 8,
el conjunto de soluciones es:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]

análisis:

En comparación con otras combinaciones, la diferencia en esta pregunta es que la matriz original contiene elementos repetidos y no puede haber combinaciones repetidas en el conjunto de soluciones. La clave es deduplicar la raíz del árbol. Por ejemplo, los tres elementos de un {1,1,2} se pueden usar como raíces, pero un [0], un [1] y un [1], un [0] son ​​duplicados, por lo que al elegir un [1] como "raíz" , es necesario determinar si el elemento se puede utilizar como "raíz". La matriz utilizada se introduce aquí para registrar el uso de cada elemento.

Al pasar a un nuevo elemento que se puede usar como "raíz", primero verifique si el elemento anterior es el mismo. Si es el mismo, mire la matriz utilizada. 若used[i - 1] == false 说明这两个节点在数结构的一层,都是等着被选做“根”的,是横着走过来的,如果used[i - 1] == true,则说明是一条树枝,是从上到下走过来的。Lo que debemos hacer para eliminar los duplicados es Haga solo uno de estos elementos repetidos. Ramas, no permita que los elementos repetidos sean las raíces del árbol nuevamente, así que omita cuando se encuentre con falso, y deje que formen una rama única cuando se encuentre con verdadero (combinación)

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

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_34612223/article/details/113920849
Recomendado
Clasificación