[LeetCode] Split Array into Fibonacci Sequence 分割数组成斐波那契序列
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 all0 <= 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 <= S.length <= 200Scontains 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即可,其余部分和上面的解法并没有啥区别,代码参见评论区一楼。
类似题目:
参考资料:
https://leetcode.com/problems/split-array-into-fibonacci-sequence/
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Split Array into Fibonacci Sequence 分割数组成斐波那契序列的更多相关文章
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- [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 ...
- 剑指offer二刷——数组专题——斐波那契数列
题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0,第1项是1). n<=39 我的想法 斐波那契数列定义:F(0)=0,F(1)=1, ...
- 冒泡排序 and 选择排序 变量打印斐波拉契数列 and 数组打印斐波拉契数列
1 排序 1.1 冒泡排序 #include <stdio.h> int main() { ]; printf("input six int numbers:\n"); ...
- LeetCode 842. Split Array into Fibonacci Sequence
原题链接在这里:https://leetcode.com/problems/split-array-into-fibonacci-sequence/ 题目: Given a string S of d ...
- [LeetCode] Split Array into Consecutive Subsequences 将数组分割成连续子序列
You are given an integer array sorted in ascending order (may contain duplicates), you need to split ...
随机推荐
- application.properties 文件和 application.yml 文件的区别
yml文件的好处,天然的树状结构,方便查看,最终会转成application.properties 注意点: 1,原有的key,例如spring.jpa.properties.hibernate.di ...
- Ubuntu下使用Sublime Text 3配置Python开发环境
因为电脑配置有些低端,所以只能使用Sublime来当作Python的IDE. 1.下载Sublime Text 3并安装 首先去官网找到64位的.tar.bz2的压缩文件下载: 使用命令或归档管理器将 ...
- C语言中 if 和 else if 的区别
先看代码:我们本意是对i不同的值有不同的判断. #include<stdio.h> int main(void) { ; ) { i++; printf("%d\n", ...
- 项目Alpha冲刺(团队)-第三天冲刺
格式描述 课程名称:软件工程1916|W(福州大学) 作业要求:项目Alpha冲刺(团队)-代码规范.冲刺任务与计划 团队名称:为了交项目干杯 作业目标:描述第三天冲刺的项目进展.问题困难.心得体会 ...
- 强行杀windows服务
powershell命令:taskkill /f /fi "SERVICES eq 服务名称"
- Gitlab_ansible_jenkins三剑客②Gitlab的后台管理
系统信息和日志 健康状态 使用gitlab的用户管理和审批功能 创建用户 创建一个lead普通账号 进入test-repo仓库 这样就把dev添加到了test-repo这个项目中,并且有了develo ...
- C# 根据出生日期(年月日)计算年龄的代码
public int GetAgeByBirthdate(DateTime birthdate) { DateTime now = DateTime.Now; int age = now.Year - ...
- windows 下 配置 github
github 功能介绍 1. 记录多个版本 2.查看历史操作,可以进行版本回退和前进的控制 3. 多端共享代码,自动合成 Github 与 SVN 1. SVN 版本集中管理,所 ...
- jQuery概念
- window 服务器 安装 sql server 2008 r2 express 并启用远程访问
目前市面上的数据库服务器虽然好,但是并不便宜,一个月数千RMB, 我们可以通过在已有的数据库上自建数据库来解决 目前已知的SQL Server 2008 R2的版本有: 企业版.标准版.工作组版.We ...