[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 ...
随机推荐
- 医学图像数据(一)——TCIA基本介绍
1.介绍 The Cancer Imaging Archive (TCIA)是癌症研究的医学图像的开放获取数据库.该网站由国家癌症研究所(NCI)癌症影像计划资助,合同由阿肯色大学医学科学院管理.存档 ...
- SpringSecurity在Springboot下使用的初步体验
SpringSecurity曾经在十年前非常火热,只要是做权限系统,当时几乎非用它不可,记得是在XML文件里一堆的配置.曾几何时,Shiro冒了出来,以其简洁和轻量的风格慢慢地捕获了众多码农的心,从此 ...
- 初识中间件Kafka
初识中间件Kafka Author:SimplelWu 什么是消息中间件? 非底层操作系统软件,非业务应用软件,不是直接给最终用户使用的,不能直接给客户带来价值的软件统称为中间件 关注于数据的发送和接 ...
- Java 批量修改文件夹里面的文件的名字
背景:公司要求使用PADS完成原理图设计.PCB Layout.而他硬件工程师要求我在将PADS的库文件发送给他们之前,必须在每一个库文件的后面追加今天的日期,再发送给他们. 问题来了,如果一次需要发 ...
- Windows Internals 笔记——线程优先级
1.每个线程都被赋予0(最低)~31(最高)的优先级数.当系统确定给哪个线程分配CPU时,它会首先查看优先级为31的线程,并以循环的方式进行调度.如果有优先级为31的线程可供调度,那么系统就会将CPU ...
- JAVA BigDecimal 用法
一.BigDecimal 的加减乘除 BigDecimal bignum1 = new BigDecimal("10"); BigDecimal bignum2 = new Big ...
- querySelector() 选择器语法
选择器 示例 示例说明 CSS .class .intro 选择所有class="intro"的元素 1 #id #firstname 选择所有id="firstname ...
- Windows下python2与python3兼容设置
分别安装python2与python3后,我想直接通过命令python2.pip2与python3.pip3区分: 分别进入python安装目录下,修改python.exe为python2.exe.p ...
- URL在Tomcat服务器端的servlet解析过程
servlet 是Java中用于运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层. proto ...
- 史上最全的select加锁分析(Mysql)
引言 大家在面试中有没遇到面试官问你下面六句Sql的区别呢 select * from table where id = ? select * from table where id < ? s ...