【问题标题】:Find the fibonacci sum that is less than a given number in less than O(n)在小于 O(n) 的时间内找到小于给定数字的斐波那契和
【发布时间】:2017-09-15 19:53:18
【问题描述】:

我正在尝试解决一个问题,部分解决方案是找到小于输入数字的 finbonacci 数字的总和。现在输入数字的上限是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...

【问题讨论】:

标签: python algorithm lambda functional-programming


【解决方案1】:

您可以简单地使用 二分搜索(例如使用 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]

【讨论】:

  • @fazkan:搜索肯定是 O(log n) (肯定是因为元素都是不同的),正如insort_left 函数中所记录的那样。跨度>
【解决方案2】:

这可以使用矩阵求幂在 O(logn)*O(logn) 中完成,请参考下面的链接
https://math.stackexchange.com/questions/1102452/modulus-of-sum-of-sequence-of-fibonacci-numbers
如果您没有足够的内存来存储所有 10^9 的总和,您可以使用此 O(logn) 来计算第 i 个总和,如果您希望总和小于等于给定输入,您可以对 i 进行二进制搜索

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多