将数组拆分成斐波那契序列
难度:
标签:
题目描述
代码结果
运行时间: 28 ms, 内存: 16.1 MB
/*
* 思路:
* 1. 使用递归和Java Stream API进行斐波那契数列的查找。
* 2. 尝试从字符串的每个位置开始分割,使用Stream检查每个片段是否符合条件。
*/
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class SolutionStream {
public List<Integer> splitIntoFibonacci(String num) {
List<Integer> result = new ArrayList<>();
backtrack(num, result, 0);
return result;
}
private boolean backtrack(String num, List<Integer> result, int index) {
if (index == num.length() && result.size() >= 3) {
return true;
}
return IntStream.range(index, num.length())
.filter(i -> !(num.charAt(index) == '0' && i > index))
.mapToObj(i -> num.substring(index, i + 1))
.map(Long::parseLong)
.filter(numL -> numL <= Integer.MAX_VALUE)
.filter(numL -> {
int size = result.size();
return size <= 1 || numL == result.get(size - 1) + result.get(size - 2);
})
.anyMatch(numL -> {
result.add(numL.intValue());
boolean found = backtrack(num, result, index + String.valueOf(numL).length());
if (!found) {
result.remove(result.size() - 1);
}
return found;
});
}
}
解释
方法:
题解通过使用回溯法来尝试构建斐波那契序列。首先定义一个辅助函数 dfs(i),其中 i 表示当前正在处理的数字的起始位置。如果 i 等于字符串的长度且答案列表中至少有三个数,说明已经成功构建了一个序列,函数返回 True。然后逐个检查可能的数字,如果遇到以 '0' 开头的数字(并且长度超过1),则跳出循环。对每一个可能的数字,检查是否符合斐波那契序列的要求:1) 数字不能超过 2^31 - 1;2) 如果列表中已有至少两个数,该数必须等于最后两个数的和。如果当前数字满足要求,将其加入到序列中并递归调用 dfs(j+1)。如果递归调用返回 True,表示找到了合法的序列,当前函数也返回 True。如果当前路径不行,则将最后一个数字从序列中移除(回溯),尝试下一个可能的数字。如果所有可能都尝试完毕,返回 False。
时间复杂度:
O(2^n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在解决这个问题时选择使用回溯法而不是其他算法如动态规划?
▷🦆
在处理以 '0' 开头的数字时,为什么只有当数字长度超过1时才跳过,而单个'0'是被接受的?
▷🦆
函数中检查`x > 2**31 - 1`的原因是什么,考虑到Python的int类型是动态大小的,这一检查的目的是什么?
▷🦆
在`ans`列表中需要至少两个数时,使用`ans[-2] + ans[-1] == x`来检查当前数字x是否可以添加到列表中。这种方法是否可能因为整数溢出而导致问题?
▷相关问题
累加数
累加数 是一个字符串,组成它的数字可以形成累加序列。
一个有效的 累加序列 必须 至少 包含 3 个数。除了最开始的两个数以外,序列中的每个后续数字必须是它之前两个数字之和。
给你一个只包含数字 '0'-'9'
的字符串,编写一个算法来判断给定输入是否是 累加数 。如果是,返回 true
;否则,返回 false
。
说明:累加序列里的数,除数字 0 之外,不会 以 0 开头,所以不会出现 1, 2, 03
或者 1, 02, 3
的情况。
示例 1:
输入:"112358"
输出:true 解释:累加序列为:1, 1, 2, 3, 5, 8
。1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8
示例 2:
输入:
"199100199"
输出:true 解释:累加序列为:1, 99, 100, 199。
1 + 99 = 100, 99 + 100 = 199
提示:
1 <= num.length <= 35
num
仅由数字(0
-9
)组成
进阶:你计划如何处理由过大的整数输入导致的溢出?
斐波那契数
斐波那契数 (通常用 F(n)
表示)形成的序列称为 斐波那契数列 。该数列由 0
和 1
开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n
,请计算 F(n)
。
示例 1:
输入:n = 2 输出:1 解释:F(2) = F(1) + F(0) = 1 + 0 = 1
示例 2:
输入:n = 3 输出:2 解释:F(3) = F(2) + F(1) = 1 + 1 = 2
示例 3:
输入:n = 4 输出:3 解释:F(4) = F(3) + F(2) = 2 + 1 = 3
提示:
0 <= n <= 30