[Backtracking] [leetcode] nombre cumulé

sujet:

Le nombre cumulatif est une chaîne et les nombres qui le composent peuvent former une séquence cumulative.

Une séquence d'accumulation valide doit contenir au moins 3 nombres. À l'exception des deux premiers nombres, les autres nombres de la chaîne sont égaux à la somme des deux nombres précédents.

Étant donné une chaîne contenant uniquement les nombres «0» - «9», écrivez un algorithme pour déterminer si l'entrée donnée est un nombre cumulatif.

Explication: Le nombre dans la séquence d'accumulation ne commencera pas par 0, donc 1, 2, 03 ou 1, 02, 3 n'apparaîtra pas.

Exemple 1:

Entrée: "112358"
Sortie: vrai 
Explication: La séquence d'accumulation est: 1, 1, 2, 3, 5, 8. 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
Exemple 2:

Entrée: "199100199"
Sortie: vrai 
Explication: La séquence cumulative est: 1, 99, 100, 199. 1 + 99 = 100, 99 + 100 = 199
Avancé:
Comment gérez-vous une entrée d'entier débordante?

la source:

306. Nombre cumulatif

Idées de résolution de problèmes: retour en arrière

Cette question est similaire à la division d'une chaîne de nombres en une séquence de Fibonacci , sauf que cette question renvoie le type booléen et le nombre est très grand.

Définissez un chemin de tableau pour enregistrer le nombre de fractionnements.

  • Condition de terminaison récursive: la division de chaîne est terminée et au moins 3 nombres sont divisés
  • Conditions d'élagage: lorsque l'un est terminé, ou lorsque le premier nombre est inséré, si sa longueur dépasse la moitié de la chaîne, il ne doit pas être fractionné, ou lorsque la somme des deux premiers nombres est inférieure au nombre actuel n.
class Solution {
public:
    vector<long> path;
    bool finish;
    bool isAdditiveNumber(string S) {
        finish = false;
        // 处理开头的0
        int start = 0;
        while (start < S.size() && S[start] == '0') {
            path.push_back(0);
            start++;
        }
        back(S, start);
        return finish;
    }
    void back(const string& s, int start) {
        if (path.size() > 2 && start == s.size()) {
            finish = true;
            return;
        }
 
        // 处理开头的0
        if (s[start] == '0') {
            if (path.size() < 2) {
                path.push_back(0);
                back(s, start + 1);
                path.pop_back();
            }
            return;
        }
        long n = 0;
        for (int i = start; i < s.size(); i++) {
            if (finish) break;
            int sz = path.size();
            if ((sz == 0  && i >= s.size()/2) ||
                (sz > 1 && path[sz-1] + path[sz-2] < n)) break;
            n = n * 10 + s[i] - '0'; // n:[start,i]内的数字
            if (sz < 2 || path[sz-1] + path[sz-2] == n) {
                path.push_back(n);
                back(s, i + 1);
                path.pop_back();
            }
        }
    }
};

 

Je suppose que tu aimes

Origine blog.csdn.net/hbuxiaoshe/article/details/115250659
conseillé
Classement