算法:求斐波那契数列的第n项

斐波那契数列

斐波那契数列就是从0、1开始,每一个数等于前面两个数字之和,如下:

0 1 1 2 3 5 8 13 21 34 ...

求斐波那契数列的第n项

递归

思路

f(0) = 0
f(1) = 1
f(n) = f(n - 1) + f(n - 2)
/**
 * 斐波那契数列(递归)
 * @param n n
 */
export function fibonacci(n: number): number {
    
    
    if (n <= 0) return 0
    if (n === 1) return 1

    return fibonacci(n - 1) + fibonacci(n - 2)
}
// 正常
console.log(fibonacci(10))
// 电脑卡死
console.log(fibonacci(100))

运行数字稍微大一点之后,电脑直接卡死了,分析一下原因:
在这里插入图片描述
如图,例如当求第 10 项的时候,会依次递归求第 9 和第 8项,同时求第 9 项的时候,也会求第 8 项,那么这里求第 8 项就会重复多次,每次都会有大量的重复计算,复杂度是 O(2^n)。

循环

用循环的方法可以把上次的结果存起来,减少计算

/**
 * 斐波那契数列(循环)
 * @param n n
 */
export function fibonacci(n: number): number {
    
    
    if (n <= 0) return 0
    if (n === 1) return 1

    let n1 = 1 // 记录 n-1 的结果
    let n2 = 0 // 记录 n-2 的结果
    let res = 0

    for (let i = 2; i <= n; i++) {
    
    
        res = n1 + n2

        // 记录中间结果
        n2 = n1
        n1 = res
    }

    return res
}

单元测试

import {
    
     fibonacci } from './fibonacci'

describe('斐波那契数列', () => {
    
    
    it('0 和 1', () => {
    
    
        expect(fibonacci(0)).toBe(0)
        expect(fibonacci(1)).toBe(1)
    })
    it('正常情况', () => {
    
    
        expect(fibonacci(2)).toBe(1)
        expect(fibonacci(3)).toBe(2)
        expect(fibonacci(6)).toBe(8)
    })
    it('n 小于 0', () => {
    
    
        expect(fibonacci(-1)).toBe(0)
    })
})

猜你喜欢

转载自blog.csdn.net/weixin_43972437/article/details/130303294