数字串分割成fibonacci数列
只要前两个确定,整个分割也都确定了
bool isAdditiveNumber(string num) {
// 选头两个数字长为i和j
const int N = num.size();
for (int i = 1; i <= N / 2; i++) {
if (i > 1 && num[0] == '0') break;
for (int j = 1; j <= (N - i) / 2; j++) {
if (j > 1 && num[i] == '0') break;
if (isValid(num, i + j, num.substr(0, i), num.substr(i, j))) return true;
}
}
return false;
}
// num[idx..]开头是不是等于n1+n2
bool isValid(const string &num, int idx, const string &n1, const string &n2) {
const int N = num.size();
if (idx == N) return true;
auto sum = add(n1, n2);
int len = sum.size();
if (idx + len > N || num.substr(idx, len) != sum) return false;
return isValid(num, idx + len, n2, sum);
}
// 数字串加法可解决超大数溢出问题
string add(const string &a, const string &b) {
// return to_string(stoll(a) + stoll(b));
string ans;
int carry = 0;
int i = (int)a.size() - 1, j = (int)b.size() - 1;
while (i >= 0 || j >= 0 || carry > 0) {
if (i >= 0) carry += a[i--] - '0';
if (j >= 0) carry += b[j--] - '0';
ans.push_back(carry % 10 + '0');
carry /= 10;
}
reverse(ans.begin(), ans.end());
return ans;
}
返回所有分割,回溯法
vector<int> splitIntoFibonacci(string S) {
vector<int> ans;
search(S, 0, ans);
return ans;
}
bool search(const string &s, int idx, vector<int> &ans) {
const int N = s.size(), M = ans.size();
if (idx == N && M >= 3) return true;
// s[idx..i]分割出数num
for (int i = idx; i < N; i++) {
if (i > idx && s[idx] == '0') continue; // 多位数的首位不能为0
int len = i - idx + 1;
if (len > 10) continue; // < 2^31, 最多10位数
long num = stol(s.substr(idx, len));
if (num > INT_MAX) continue; // 太大溢出
if (M >= 2 && ans[M-2] + ans[M-1] != num) continue; // 不满足Fibonacci性质
ans.push_back(num);
if (search(s, i + 1, ans)) return true;
ans.pop_back();
}
return false;
}