tópico:
O número acumulativo é uma string e os números que o constituem podem formar uma sequência acumulativa.
Uma sequência de acumulação válida deve conter pelo menos 3 números. Exceto para os primeiros dois números, os outros números na string são iguais à soma dos dois números anteriores.
Dada uma string contendo apenas os números '0' - '9', escreva um algoritmo para determinar se a entrada fornecida é um número acumulativo.
Explicação: O número na sequência de acumulação não começará com 0, portanto 1, 2, 03 ou 1, 02, 3 não aparecerá.
Exemplo 1:
Entrada: "112358"
Saída: verdadeiro
Explicação: A sequência de acumulação é: 1, 1, 2, 3, 5, 8. 1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
Exemplo 2:
Entrada: "199100199"
Saída: verdadeiro
Explicação: A sequência cumulativa é: 1, 99, 100, 199. 1 + 99 = 100, 99 + 100 = 199
Avançado:
Como você lida com uma entrada de número inteiro transbordando?
fonte:
Ideias para resolução de problemas: retrocedendo
Esta pergunta é semelhante a dividir uma string numérica em uma sequência de Fibonacci , exceto que esta pergunta retorna o tipo bool e o número é muito grande.
Defina um caminho de matriz para registrar o número de divisões.
- Condição de terminação recursiva: a divisão da string é concluída e pelo menos 3 números são divididos
- Condições de poda: quando um é completado, ou quando o primeiro número é inserido, se seu comprimento ultrapassar a metade do fio, ele não deve ser dividido, ou quando a soma dos dois primeiros números for menor que o número atual 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();
}
}
}
};