力扣842. 将数组拆分成斐波那契序列
https://leetcode-cn.com/problems/split-array-into-fibonacci-sequence/
给定一个数字字符串 S,比如 S = "123456579",我们可以将它分成斐波那契式的序列 [123, 456, 579]。
形式上,斐波那契式序列是一个非负整数列表 F,且满足:
0 <= F[i] <= 2^31 - 1,(也就是说,每个整数都符合 32 位有符号整数类型);
F.length >= 3;
对于所有的0 <= i < F.length - 2,都有 F[i] + F[i+1] = F[i+2] 成立。
另外,请注意,将字符串拆分成小块时,每个块的数字一定不要以零开头,除非这个块是数字 0 本身。
返回从 S 拆分出来的任意一组斐波那契式的序列块,如果不能拆分则返回 []。
示例 1:
输入:"123456579"
输出:[123,456,579]
示例 2:
输入: "11235813"
输出: [1,1,2,3,5,8,13]
示例 3:
输入: "112358130"
输出: []
解释: 这项任务无法完成。
示例 4:
输入:"0123"
输出:[]
解释:每个块的数字不能以零开头,因此 "01","2","3" 不是有效答案。
示例 5:
输入: "1101111"
输出: [110, 1, 111]
解释: 输出 [11,0,11,11] 也同样被接受。
回溯算法
回溯算法模板
bool backtrack("原始参数") {
//终止条件(递归必须要有终止条件)
if ("终止条件") {
//一些逻辑操作(可有可无,视情况而定)
return true;
}
for (int i = "for循环开始的参数"; i < "for循环结束的参数"; i++) {
//一些逻辑操作(可有可无,视情况而定)
//做出选择
//递归
if(backtrack("新的参数"))return true;
//一些逻辑操作(可有可无,视情况而定)
//撤销选择
}
return false;
}
// 842splitIntoFibonacci.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include<vector>
#include<string>
using namespace std;
class Solution {
public:
vector<int> splitIntoFibonacci(string S) {
vector<int>result;
if(backtrack(result,0,S)){
return result;
}
else
{
vector<int>resulttemp;
return resulttemp;
}
}
bool backtrack(vector<int>&result,int index,string S) {
//终止条件(递归必须要有终止条件)
//边界条件判断,如果截取完了,并且res长度大于等于3,表示找到了一个组合。
if (index==S.length() && result.size()>=3)
{
return true;
}
for (int i = index; i < S.length(); i++)
{
//两位以上的数字不能以0开头
if (S[index]=='0' && i>index)
{
break;
}
//截取字符串转化为数字
long long num = stringtonum(S,index,i+1);
//如果截取的数字大于int的最大值,则终止截取,代表到最末尾了
if (num>INT_MAX)
{
break;
}
//做出选择
int resultsize = result.size();
//如果截取的数字大于result中前两个数字的和,说明这次截取的太大,直接终止,因为后面越截取越大
if (resultsize>=2 && num>((long long)result[resultsize-1]+ (long long)result[resultsize - 2]))
{
//
break;
}
//如果截取的数字小于result中前两个数字的和,说明这次截取的太小,continue,继续后移
if (resultsize >= 2 && num < ((long long)result[resultsize - 1] + (long long)result[resultsize - 2]))
{
continue;
}
//先把数字num添加到集合result中
result.push_back(num);
//递归
//如果找到了就直接返回
if (backtrack(result,i+1,S))
{
return true;
}
//撤销选择
//如果没找到,就会走回溯这一步,然后把上一步添加到集合res中的数字给移除掉
result.pop_back();
}
return false;
}
//相当于截取字符串S中的子串然后转换为十进制数字
long long stringtonum(string S,int start,int end) {
long long num = 0;
for (int i = start; i < end; i++)
{
num = num * 10 + (S[i] - 48);
}
return num;
}
};
int main()
{
Solution s;
string S;
S = "214748364721474836422147483641";
auto result = s.splitIntoFibonacci(S);
for (int i = 0; i < result.size(); i++)
{
cout << result[i] << " ";
}
cout << "\n";
std::cout << "Hello World!\n";
}