leetcode-斐波拉契数列(js)

认识斐波拉契数列

第n 个数由数列的前两个相加而来: f(n) = f(n - 1) + f(n -2),用代码实现斐波拉契数列,无非就是要考察递归的写法,但是,单纯使用递归,在严格要求时间复杂度和空间复杂度上是不可行的,因为他做了无数次无用的计算.

1, 1, 2, 3, 5, 8, 13, …

普通实现 (递归)

这种方式计算的时候会有很多重复的计算,而且递归的层数越来越深容易递归爆栈。

const fib = n => n <= 1 ? n :fib(n-1)+fib(n-2)
console.log(fib(5))

减少时间复杂度(闭包+递归)

通过增加一层缓存,用来存放之前已经计算过的数值,当需要计算新值的时候先通过查找缓存,缓存命中则直接返回,未命中再继续计算。但是使用了数组,增加了空间复杂度.

const fib3 = function (n) {
  n <= 1 && n
  const cache = []
  cache[0] = 1
  cache[1] = 1
  function memoize(num) {
      if (cache[num] !== undefined) {
          return cache[num]
      }
      cache[num] = memoize(num - 1) + memoize(num - 2)
      // console.log(cache[num])
      return cache[num]
  }
  const result = memoize(n-1)
  return result
}
console.log(fib3(4))

但是这样的实现方式有一个问题,如果不是依次计算斐波那契数列就会增加额外的消耗,比如直接计算 fib(1000) ,这个时候数组中会先初始化中间的其他数组项为 undefined 这里会小一些时间,但是计算完毕之后1-1000之间的斐波那契数列都填充完毕了。
参考网上的一种解法是用对象替换数组来进行缓存,这样就少去了填充 undefined 的时间

// 闭包 + 缓存对象
const fibonacci = (function () {
  const f = {}
  return function(n) {
    if(n === 0 || n === 1) {
      return n
    }
    if(f[n-2] === undefined) {
      f[n-2] = fibonacci(n-2)
    }
    if(f[n-1] === undefined) {
      f[n-1] = fibonacci(n-1)
    }
    return f[n] = f[n-1] + f[n-2]
  }
})()

换一种从前往后算的写法:::从前面的数一步一步的往后计算一直计算到n

const fib =function (n){
  n <= 1 && n
  const cache = []
  cache[0] = 1
  cache[1] = 1
  for (let i= 2; i<=n; i++ ) {
    cache[i] = cache[i-1] +cache[i-2]
  }
  return cache[n-1]
}
console.log(fib(5))

减少空间复杂度

不使用和数组,减少空间维度 从前往后算

const fib = n =>{
    n <= 1 && n
    let prev2 = 0
    let prev1 = 1
    let result = 0
    for (let i = 2;i<=n;i++) {
      result =prev2+prev1
      prev2 = prev1
      prev1 = result
    }
    return result
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值