斐波那契数列
斐波那契数列就是从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)
})
})