Python算法題----玩轉fibonacci數列

    fibonacci數列是個很常見的面試題,相信你們都見識過,反正我遇見過兩次。遞歸是最容易想到的辦法。可是寫一個遞歸,每每面試官並不滿意,會追問。這個遞歸存在什麼問題啊。有沒有其它辦法啊……。辦法總比問題多,跳跳大路通帝都。下面就總結一下。把程序寫到面試官的心縫裏!python


遞歸法面試

這個遞歸存在的最嚴重的問題就是重複計算,在代碼的遞歸分支裏能夠看到函數被遞歸調用了兩次,那麼不少函數其實都被重複計算了。最後再來解決這個問題。緩存

def fib01(n):
    if n == 1 or n == 2:
        return n
    else:
        return fib01(n-1) + fib01(n-2)



遞推法1app

使用一個列表來存儲整個fibonnci數列,所求的即爲列表的第n項ide

def fib02(n):
    if n == 1 or n == 2:
        return n
    else:
        arr = [1, 1, 2]
        i = 3
        for i in range(3, n+1):
            arr.append(arr[i-1] + arr[i-2])
        return arr[n]

遞推法2函數

聲明幾個歷史變量不斷計算數列的值,而且交換變量spa

def fib03(n):
    if n == 1 or n == 2:
        return n
    else:
        x = 1
        y = 2
        for i in range(3, n+1):
            fi = x + y
            x = y
            y = fi
        return y


緩存遞歸中間結果
orm

定義一個字典,將遞歸函數的計算結果存入_fib_cache,每次判斷該函數是否在緩存中,在直接返回,不在,計算並放入緩存遞歸

_fib_cache = {}
def fib04(n):
    if n in _fib_cache:
        return _fib_cache[n]
    else:
        _fib_cache[n] = n if n <= 2 else fib04(n-1) + fib04(n-2)
        return _fib_cache[n]


有了緩存,生活美好了不少,可是看着有點彆扭。孤零零的_fib_cache,弄個裝飾器多好,這明顯能夠有個裝飾器的。ci


函數裝飾器

def memo(f):
    cache = {}

    def decorated(*args):
        if args in cache:
            return cache[args]
        else:
            cache[args] = f(*args)
            return cache[args]

    return decorated

有了這個裝飾器函數,咱們就能夠裝飾咱們的遞歸函數了

@memo
def fib01(n):
    if n == 1 or n == 2:
        return n
    else:
        return fib01(n-1) + fib01(n-2)
相關文章
相關標籤/搜索