《每日一题》842. 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] 也同样被接受。
提示:
1 <= S.length <= 200
- 字符串
S
中只含有数字。
回溯+剪枝
使用列表存储拆分出的数,回溯过程中维护该列表的元素,列表初始为空。遍历字符串的所有可能的前缀,作为当前被拆分出的数,然后对剩余部分继续拆分,直到整个字符串拆分完毕。
根据斐波那契式序列的要求,从第 333 个数开始,每个数都等于前 222 个数的和,因此从第 333 个数开始,需要判断拆分出的数是否等于前 222 个数的和,只有满足要求时才进行拆分,否则不进行拆分。
回溯过程中,还有三处可以进行剪枝操作。
拆分出的数如果不是 000,则不能以 000 开头,因此如果字符串剩下的部分以 000 开头,就不需要考虑拆分出长度大于 111 的数,因为长度大于 111 的数以 000 开头是不符合要求的,不可能继续拆分得到斐波那契式序列;
拆分出的数必须符合 323232 位有符号整数类型,即每个数必须在 [0,231−1][0,2^{31}-1][0,231−1] 的范围内,如果拆分出的数大于 231−12^{31}-1231−1,则不符合要求,长度更大的数的数值也一定更大,一定也大于 231−12^{31}-1231−1,因此不可能继续拆分得到斐波那契式序列;
如果列表中至少有 222 个数,并且拆分出的数已经大于最后 222 个数的和,就不需要继续尝试拆分了。
当整个字符串拆分完毕时,如果列表中至少有 333 个数,则得到一个符合要求的斐波那契式序列,返回列表。如果没有找到符合要求的斐波那契式序列,则返回空列表。
Python
class Solution:def splitIntoFibonacci(self, S: str) -> List[int]:def backtrack(index: int):if index == len(S):return len(ans) >= 3curr = 0for i in range(index, len(S)):if i > index and S[index] == "0":breakcurr = curr * 10 + ord(S[i]) - ord("0")if curr > 2 ** 31 - 1:breakif len(ans) < 2 or curr == ans[-2] + ans[-1]:ans.append(curr)if backtrack(i + 1):return Trueans.pop()elif len(ans) > 2 and curr > ans[-2] + ans[-1]:breakreturn Falseans = list()backtrack(0)return ans
复杂度分析
时间复杂度:O(nlog2C)O(n \log^2 C)O(nlog2C),其中 nnn 是字符串的长度,CCC 是题目规定的整数范围 231−12^{31}-1231−1。在回溯的过程中,实际上真正进行「回溯」的只有前 222 个数,而从第 333 个数开始,整个斐波那契数列是可以被唯一确定的,整个回溯过程只起到验证(而不是枚举)的作用。对于前 222 个数,它们的位数不能超过 ⌊log10C⌋\lfloor \log_{10} C \rfloor⌊log10C⌋,那么枚举的空间为 O(log2C)O(\log^2 C)O(log2C);对于后面的所有数,回溯的过程是没有「分支」的,因此时间复杂度为 O(n)O(n)O(n),相乘即可得到总时间复杂度 O(nlog2C)O(n \log^2 C)O(nlog2C)。
空间复杂度:O(n)O(n)O(n),其中 nnn 是字符串的长度。除了返回值以外,空间复杂度主要取决于回溯过程中的递归调用层数,最大为 nnn。
《每日一题》842. Split Array into Fibonacci Sequence 将数组拆分成斐波那契序列相关推荐
- 842. 将数组拆分成斐波那契序列
链接:842. 将数组拆分成斐波那契序列 题解: class Solution {public:vector<int> splitIntoFibonacci(string S) {vect ...
- Leetcode每日一题:842.split-array-into-fibonacci-sequenc(将数组拆分成斐波那契序列)
思路:深度优先搜索,设定最后返回的数组vec,每次搜索只处理一个数,这数可以取1位,也可以取很多位,这取决于前面两个放入vec的数的和(vec只有两个及以下的数时,直接放入),如果无法等于他俩的和,那 ...
- leetcode 842. 将数组拆分成斐波那契序列(回溯算法)
给定一个数字字符串 S,比如 S = "123456579",我们可以将它分成斐波那契式的序列 [123, 456, 579]. 形式上,斐波那契式序列是一个非负整数列表 F,且满 ...
- LeetCode 842. 将数组拆分成斐波那契序列(暴力查找)
1. 题目 给定一个数字字符串 S,比如 S = "123456579",我们可以将它分成斐波那契式的序列 [123, 456, 579]. 形式上,斐波那契式序列是一个非负整数列 ...
- 842. Split Array into Fibonacci Sequence
文章目录 1 题目理解 2 回溯 1 题目理解 输入:一个数字字符串S.例如S="123456579". 规则:我们可以把这个字符串分割为菲波那切数列,例如:[123, 456, ...
- JavaScript实现以数组形式返回斐波那契数列fibonacci算法(附完整源码)
JavaScript实现以数组形式返回斐波那契数列fibonacci算法(附完整源码) fibonacci.js完整源代码 fibonacci.js完整源代码 export default funct ...
- 斐波那契序列 Fibonacci
[定理1] 标准Fibonacci序列(即第0项为0,第1项为1的序列)当N大于1时,一定有f(N)和f(N-1)互质 其实,结合"互质"的定义,和一个很经典的算法就可以轻松证明 ...
- java解决斐波那契数列(Fibonacci sequence)
斐波那契数列(Fibonacci sequence)的定义:斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610 ...
- C#,斐波那契数列(Fibonacci Sequence)的八种算法与源代码
一.莱昂纳多·斐波那契(Leonardo Fibonacci) 斐波那契公元1170年生于意大利比萨,卒于1250年,被人称作"比萨的莱昂纳多",是一名闻名于欧洲的数学家,其主要的 ...
最新文章
- 《阿里云前端技术周刊》第五期
- paper 68 :MATLAB中取整函数(fix, floor, ceil, round)的使用
- 【线性表4】线性表的链式实现:静态表
- 给git配置http代理
- 关于Windows azure从github上部署项目
- JAVA中常用接口的介绍及使用示例 java lang Comparable
- android 打开下载管理器,Android OkHttp 下载管理器
- 容器技术Docker K8s 20 容器服务ACK基础与进阶-存储管理
- 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号
- 2020中科院信工所夏令营面试
- 速达3000 数据库备份文件分析
- install index.php,安装好的织梦dedecms首页index.php自动跳转到install/index.php的问题
- ps怎么保存一小块的图片_ps中怎么保存图片
- [置顶]什么样的 CEO 是伟大的?
- 教你一键制作纯净Win10系统安装盘
- csdn添加新浪微博组件
- 运营小白如何搭建【初期用户生命周期体系】
- 12306买的票如何报销?可以网上打印吗?
- 单表代替和多表代替密码体系
- java智慧农业系统-农业云端农产品仓储子系统