剑指 offer10. 斐波那契数列 -- JavaScript解法

什么是斐波那契数列呢?我们可以理解为它是这样的一个数列:1,1,2,3,5,8…n。该数列前两项相加等于下一项,以此类推。数学公式表示为:
f(0) = 0 n = 0
f(1) = 1 n = 1
f(n) = f(n - 1) + f(n - 2) n>1

斐波那契数列可以衍生为一些实际问题,比如爬楼梯问题、兔子繁殖问题等。

题目要求

在这里插入图片描述

解题思路

1、暴力求解

function fib(n){
	if(n == 1) return 1;
	if(n == 2) return 1;
	return fib(n - 1) + fib(n - 2);
}

但是这道题用递归并不是最优解,因为它存在很严重的效率问题,比如,求解f(10),我们先求出f(9)+f(8),再求f(9),必须先得到f(8)+f(7)…,可以用二叉树来表示这种依赖关系,如下图:
在这里插入图片描述
树中存在很多重复的节点。并且,重复的节点会随着n的增大而急剧增大。所以,这种方式并不合适。优化点,避免重复元素的重复计算,可以把中间的到的中间项保存起来,在下次需要计算的时候先查找下是否存在,已存在则不需重复计算。

2、dp数组迭代法

var fib = function(n) {
  let dp = [0,1]
  for(let i = 2;i <= n;i++){
    dp[i] = dp[i - 1] + dp[i - 2]
  }
  return dp[n]
}; 

dp数组可以用两个两边代替,节省空间复杂度,降为 O(1)。

3、优化

var fib = function(n) {
  if(n <= 1) { return n };
  let prev = 0;
  let curr = 1;
  let sum = 0;
  for(let i = 2;i <= n;i++){
    sum = (curr + prev) % 1000000007; //注意取模,防止溢出
    prev = curr;
    curr = sum;
  }
  return sum; 
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值