Given a string S of digits, such as S = "123456579", we can split it into a Fibonacci-like sequence [123, 456, 579].

Formally, a Fibonacci-like sequence is a list F of non-negative integers such that:

  • 0 <= F[i] <= 2^31 - 1, (that is, each integer fits a 32-bit signed integer type);
  • F.length >= 3;
  • and F[i] + F[i+1] = F[i+2] for all 0 <= i < F.length - 2.

Also, note that when splitting the string into pieces, each piece must not have extra leading zeroes, except if the piece is the number 0 itself.

Return any Fibonacci-like sequence split from S, or return [] if it cannot be done.

Example 1:

Input: "123456579"
Output: [123,456,579]

Example 2:

Input: "11235813"
Output: [1,1,2,3,5,8,13]

Example 3:

Input: "112358130"
Output: []
Explanation: The task is impossible.

Example 4:

Input: "0123"
Output: []
Explanation: Leading zeroes are not allowed, so "01", "2", "3" is not valid.

Example 5:

Input: "1101111"
Output: [110, 1, 111]
Explanation: The output [11, 0, 11, 11] would also be accepted.

Note:

  1. 1 <= S.length <= 200
  2. S contains only digits.

这道题给了我们一个字符串,让我们分割成斐波那契序列,至少要分成三个数,并且满足斐波那契数列的性质。关于其性质,博主有个口诀可以快速记忆,那就是大学食堂里今天的汤是昨天的汤加上前天的汤。题目中给的例子挺多的,便于理解题意,其中例子4还强调了不能有leading zeros。但是关于overflow的test case却只字未提,害的博主fail了N多次,才最终handle了所有的溢出的错误。由例子5我们可以看出,符合题意的数列其实可能不止一种,但是本题就让返回一个就行了。不管返回几个,总之不是求极值,DP在这里就不好使了,只能用递归了,由于不知道如何分割,所以肯定需要遍历所有的情况。我们用一个数组out来记录已经组成的序列,用结果res来保存结果。当out数组的个数大于等于3,并且已经遍历完了字符串S,那么此时就是可以把out数组中的内存赋值给结果res了,那么之后只要检测结果res不为空时,直接返回就可以了,这是个很好的剪枝操作,因为此题只需要一个正确答案即可(返回所有情况将作为follow up在本文的底部讨论)。

现在来考虑递归函数的主体该怎么写,既然不知道要如何分割,那么就要尝试所有的情况,一个数字,两个数字,一直到末尾,那么就可以遍历字符串S,然后取子串即可。但从什么位置开始呢,每次都从头吗,这道题都数字不能重复使用,所以应该用个变量start来记录当前遍历到的位置,那么我们从start位置起,每次取 i-start+1 长度的子串 cur,此时在转为int之前,需要先处理leading zeros的情况,判断若cur长度大于1,且首字符为0,直接break,还就是若cur的长度大于10,也break,为啥呢?因为整型的最大值是 2147483647,只有10位,所以当cur长度大于10时,一定会溢出。当cur长度为10时,也有可能溢出,这个在之后处理。好,现在将cur转为长整型 long,因为长度为10也可能溢出,所以要先转为长整型,然后在判断若大于整型最大值 INT_MAX,直接break。接下来就要考虑是否要加入out数组了,当out数字的个数不到2个的时候,我们可以直接加入当前数字,若大于等于2个,需要考虑是否满足斐波纳切数列的性质,即当前数字是否等于前两个数字之和,满足的话才加入,不然就跳过,注意这里不能直接break,因为之后的数字也许可能满足要求。加入out数组之后,就可以调用递归了,此时起始位置传入 i+1,之后再恢复out的状态即可,参见代码如下:

class Solution {
public:
vector<int> splitIntoFibonacci(string S) {
vector<int> res, out;
helper(S, , out, res);
return res;
}
void helper(string& S, int start, vector<int>& out, vector<int>& res) {
if (!res.empty()) return;
if (start >= S.size() && out.size() >= ) {
res = out; return;
}
for (int i = start; i < S.size(); ++i) {
string cur = S.substr(start, i - start + );
if ((cur.size() > && cur[] == '') || cur.size() > ) break;
long num = stol(cur), len = out.size();
if (num > INT_MAX) break;
if (out.size() >= && num != (long)out[len - ] + out[len - ]) continue;
out.push_back(num);
helper(S, i + , out, res);
out.pop_back();
}
}
};

讨论:这道题只让我们返回了一个斐波那契数列,一个很好的follow up就是返回所有满足题意的序列,就像例子5一样,把两种符合题意的组合都返回出来。其实改起来相当的容易,只需要将结果res换成一个二维数组来保存所有的情况,然后在递归函数中,首先判断如果已经遍历到了S的末尾,并且out数组中的个数大于等于3了,那么将out数组加入结果res即可,其余部分和上面的解法并没有啥区别,代码参见评论区一楼。

类似题目:

Additive Number

Fibonacci Number

参考资料:

https://leetcode.com/problems/split-array-into-fibonacci-sequence/

https://leetcode.com/problems/split-array-into-fibonacci-sequence/discuss/133936/short-and-fast-backtracking-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Split Array into Fibonacci Sequence 分割数组成斐波那契序列的更多相关文章

  1. [LeetCode] Split Array With Same Average 分割数组成相同平均值的小数组

    In a given integer array A, we must move every element of A to either list B or list C. (B and C ini ...

  2. [LeetCode] Split Array with Equal Sum 分割数组成和相同的子数组

    Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies fol ...

  3. [LeetCode] Length of Longest Fibonacci Subsequence 最长的斐波那契序列长度

    A sequence X_1, X_2, ..., X_n is fibonacci-like if: n >= 3 X_i + X_{i+1} = X_{i+2} for all i + 2 ...

  4. [Swift]LeetCode842. 将数组拆分成斐波那契序列 | Split Array into Fibonacci Sequence

    Given a string S of digits, such as S = "123456579", we can split it into a Fibonacci-like ...

  5. [LeetCode] 548. Split Array with Equal Sum 分割数组成和相同的子数组

    Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies fol ...

  6. 剑指offer二刷——数组专题——斐波那契数列

    题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1). n<=39 我的想法 斐波那契数列定义:F(0)=0,F(1)=1, ...

  7. 冒泡排序 and 选择排序 变量打印斐波拉契数列 and 数组打印斐波拉契数列

    1 排序 1.1 冒泡排序 #include <stdio.h> int main() { ]; printf("input six int numbers:\n"); ...

  8. LeetCode 842. Split Array into Fibonacci Sequence

    原题链接在这里:https://leetcode.com/problems/split-array-into-fibonacci-sequence/ 题目: Given a string S of d ...

  9. [LeetCode] Split Array into Consecutive Subsequences 将数组分割成连续子序列

    You are given an integer array sorted in ascending order (may contain duplicates), you need to split ...

随机推荐

  1. Python中字符串二三事

    首先说两个运算符: " == " 运算符测试值的等价性,递归地比较所有内嵌对象 " is " 表达式测试对象的同一性,测试两者是否为同一对象(是否为同一地址) ...

  2. Web前端-网站首页和注册界面的实现

    首页用到的知识如下: 1.bootstrap框架 2.jQuerry实现页面定时弹出广告 注册界面用到的知识: 1.bootstrap框架 2.jQuerry实现省市联动操作 3.jQuerry实现表 ...

  3. C#多条件查出来的多个DataSet,然后循环将数据整合

    private List<string> barList;        public List<string> BarList        {            get ...

  4. Ubuntu 14.04 升级 nginx/1.8.1

    参考文档:https://segmentfault.com/a/1190000008116875 https://www.ilanni.com/?p=11788 先停止nginx服务 service ...

  5. Linux 常用命令介绍

    介绍常用命令,在忘记时便于即使查询 复制.移动.删除     cp.mv.rm.pwd 1. CP 介绍 用法:CP [-adfilprsu]  源文件  目标文件 参数:参数说明: -a:是指arc ...

  6. Windbg分析蓝屏Dump文件

    一.WinDbg是什么?它能做什么? WinDbg是在windows平台下,强大的用户态和内核态调试工具.它能够通过dmp文件轻松的定位到问题根源,可用于分析蓝屏.程序崩溃(IE崩溃)原因,是我们日常 ...

  7. echarts 自定义配置带单位的 tooltip 提示框方法 和 圆环数据 tooltip 过长超出屏幕

    -------tip1-------- 在 tooltip  里边配置:拼接字符串: tooltip : { trigger: 'axis', formatter:function(params) { ...

  8. Nginx+IIS+asp.net mvc 实现负载均衡示例

    一.Nginx官网 http://nginx.org/ 二.下载并安装Nginx 下载地址:http://nginx.org/en/download.html 启动Nginx,启动成功的话可以在任务管 ...

  9. layui学习

    layui代码生成器 https://9499574.github.io/layui-form-create/ layui界面生成器 http://layuiout.magicalcoder.com/ ...

  10. jackson json转bean忽略没有的字段 not marked as ignorable

    @JsonIgnore注解用来忽略某些字段,可以用在Field或者Getter方法上,用在Setter方法时,和Filed效果一样.这个注解只能用在POJO存在的字段要忽略的情况,不能满足现在需要的情 ...