python - 在小于 O(n) 的时间内找到小于给定数字的斐波那契和

标签 python algorithm lambda functional-programming

我正在尝试解决一个问题,部分解决方案是找到小于输入数的芬波那契数之和。现在输入数字的上限是10**9。我已将问题简化为以下 O(n) 解决方案,我想知道是否有更有效的解决方案。

b=[1, 2, 4, 7, 12, 20, 33, 54, 88, 143, 232, 376, 609, 986, 1596, 2583, 4180, 6764, 
10945, 17710, 28656, 46367, 75024, 121392, 196417, 317810, 514228, 832039, 
1346268, 2178308, 3524577, 5702886, 9227464, 14930351, 24157816, 
39088168, 63245985, 102334154, 165580140, 267914295, 433494436, 701408732, 1134903169, 1836311902]

def test_lambda(a):
    list_numbers= filter(lambda x: x<=a, b)
    return len(list_numbers)

如您所见,我正在将列表 b 的值与给定输入进行比较,并返回小于给定数字的元素。

b 是到该索引为止的斐波那契数和的列表,因此第一个数字是 1,总和是 1,第二个是 1 总和是 2,第三个 2 总和是 4...

最佳答案

您可以简单地使用二进制搜索(例如使用 bisect_right 函数):

from bisect import bisect_right

def test_lambda(a):
    return bisect_right(list_numbers,a)

或者如果你想要小于输入数字的总和,你可以使用:

from bisect import bisect_right

def less_than(a):
    return a[bisect_right(list_numbers,a)-1]

这是有效的,因为列表是预先计算的并且是严格递增的。所以这意味着它是一个有序列表。二进制搜索在 O(log n) 中工作,因此可以高效地完成搜索。此外,我会将 0 添加到列表中(在第一个位置),这样以 0 作为输入的查询也会得到解析:

from bisect import bisect_right

b=[0, 1, 2, 4, 7, 12, 20, 33, 54, 88, 143, 232, 376, 609, 986, 1596, 2583, 
   4180, 6764, 10945, 17710, 28656, 46367, 75024, 121392, 196417, 317810,
   514228, 832039, 1346268, 2178308, 3524577, 5702886, 9227464, 14930351,
   24157816, 39088168, 63245985, 102334154, 165580140, 267914295, 433494436,
   701408732, 1134903169, 1836311902
  ]

def less_than(a):
    return a[bisect_right(list_numbers,a)-1]

关于python - 在小于 O(n) 的时间内找到小于给定数字的斐波那契和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45488137/

相关文章:

algorithm - 我可以使用哪种算法将加权对象平均分配给 n 个部分?

java - 匿名内部类的集合操作

amazon-web-services - 无法从 Visual Studio 2017 发布到 AWS Lambda

python - CSV 文件创建问题

python - 当我尝试从 Python 调用 Jira 项目时,出现 JSON 错误

algorithm - 这个断词算法的时间复杂度是多少? (动态规划)

c++ - 为什么这里的大括号和圆括号初始化之间存在差异?

python - 将索引数组映射到坐标数组

Python 和 scikit 学习 : replace matrix vector product during training with custom call

c# - 在 Unity 运行时删除重复的顶点