简体   繁体   English

查找斐波那契一致子数组的总和

[英]Finding sum of a fibonacci consistent subarray

We have an input integer let's say 13. We can find consistent subarray of fibonacci numbers that sums to 10 - [2,3,5].我们有一个输入整数,比方说 13。我们可以找到总和为 10 - [2,3,5] 的斐波那契数列的一致子数组。 I need to find next number that is not a sum of consistent subarray.我需要找到下一个不是一致子数组之和的数字。 In this case this number will be 14. I have this code, but the catch is, it can be optimized to not iterate through all of the N's from starting Left Pointer = 1 and Right Pointer = 1 but somehow "import" from previous N and i have no clue how to do it so maybe someone smarter might help.在这种情况下,这个数字将是 14。我有这个代码,但问题是,它可以优化为不从左指针 = 1 和右指针 = 1 开始迭代所有 N,但不知何故从前 N 中“导入”我不知道该怎么做,所以也许更聪明的人可能会有所帮助。

def fib(n):
    if n == 1: return 1
    if n == 2: return 1
    return fib(n-1) + fib(n-2)


def fibosubarr(n):
    L_pointer = 1
    R_pointer = 2
    sumfibs = 1
    while sumfibs != n:

        if sumfibs > n and L_pointer < R_pointer:
            sumfibs -= fib(L_pointer)
            L_pointer += 1

        elif sumfibs < n and L_poiner < R_pointer:
            sumfibs += fib(R_pointer)
            R_pointer += 1

        else: return False
    return True
    
n = int(input())

while fibosubarr(n):
    n += 1
print(n)

Here's a technique called "memoizing".这是一种称为“记忆”的技术。 The fib function here keeps track of the current list and only extends it as necessary.这里的fib函数会跟踪当前列表并仅在必要时对其进行扩展。 Once it has generated a number, it doesn't need to do it again.一旦它生成了一个数字,它就不需要再做一次。

_fib = [1,1]
def fib(n):
    while len(_fib) <= n:
        _fib.append( _fib[-2]+_fib[-1] )
    return _fib[n]

With your scheme, 200000 caused a noticeable delay.使用您的方案,200000 造成了明显的延迟。 With this scheme, even 2 billion runs instantaneously.有了这个方案,即使是 20 亿次也能瞬间运行。

To get the next subarray sum, you only need one call of the function -- provided you keep track of the least sum value that was exceeding n .要获得下一个子数组总和,您只需要调用一次该函数——只要您跟踪超过n最小总和值。

I would also use a generator for the Fibonacci numbers:我还会为斐波那契数列使用生成器:

def genfib():
    a = 1
    b = 1
    while True:
        yield b
        a, b = b, a + b

def fibosubarr(n):
    left = genfib()
    right = genfib()

    sumfibs = next(right)
    closest = float("inf")
    while sumfibs:
        if sumfibs > n:
            closest = min(sumfibs, closest)
            sumfibs -= next(left)
        elif sumfibs < n:
            sumfibs += next(right)
        else:
            return n
    return closest

Now you can do as you did -- produce the next valid sum that is at least the input value:现在你可以像你一样做——产生至少是输入值的下一个有效总和:

n = int(input())
print(fibosubarr(n))

You could also loop to go from one such sum to the next:你也可以循环从一个这样的总和到下一个:

n = 0
for _ in range(10):  # first 10 such sums
    n = fibosubarr(n+1)
    print(n)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM