试输出斐波那契数列的前10项

这篇博客探讨了如何通过递归和数组两种方式实现斐波那契数列的前10项,并指出在递归方法中存在大量重复计算。为了解决这个问题,提出了使用缓存对象存储已计算结果的方法,从而减少计算次数。通过缓存优化后的代码展示了如何避免重复计算并提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试题:

1、试输出斐波那契数列的前10项,即1、1、2、3、5、8、13、21、34、55。

方法1:使用递归

    // 创建一个函数,功能是返回下标为 n 的这项的数字
    function fib (n) {
      // 看下标 n 是不是 0 或者是不是 1, 如果是,就返回常数 1,如果不是就递归
      var v = n === 0 || n === 1 ? 1 : fib(n - 1) + fib(n - 2)
      return v
    }
    // var num = fib(5)
    // console.log(num)
    for (let i = 0; i <= 9; i++) {
      console.log(fib(i))
    }

方法2:使用数组

    var arr = [1, 1]
    while (arr.length < 10) {
      arr.push(arr[arr.length - 1] + arr[arr.length - 2])
    }
    console.log(arr) // [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

2、然后请思考,代码是否有大量重复的计算?应该如何解决重复计算的问题?

这张图表示了执行顺序,每计算一个结果需要从 fib(0) 和 fib(1) 开始往上计算,这样就会重复很多计算结果
在这里插入图片描述

声明一个缓存对象,把每次传入的 n 作为 key,计算结果作为 value ,储存到 cache 对象中,下次遇到 相同的 n , 就不再重新计算,而是直接使用之前计算出的结果,这样可以省略计算次数。
缓存对象格式是这样的: {2: 2, 3: 3, 4: 5, 5: 8, 6: 13, 7: 21, 8: 34, 9: 55}

    // 缓存对象,把每次传入的 n 作为 key,计算结果作为 value ,储存到 cache 对象中,下次遇到 相同的 n , 就不再重新计算,而是直接使用之前计算出的结果,这样可以省略计算次数
    var cache = {}
        
    // 创建一个函数,功能是返回下标为 n 的这项的数字
    function fib (n) {
      console.count('运行次数是:')
      // 判断缓存对象中有没有这个属性,如果有,直接用n对应的计算结果值
      if (cache.hasOwnProperty(n)) {
        return cache[n]
      }
      // 缓存对象咩有这个值
      // 看下标 n 是不是 0 或者是不是 1, 如果是,就返回常数 1,如果不是就递归
      var v = n === 0 || n === 1 ? 1 : fib(n - 1) + fib(n - 2)
      // 计算结果写入缓存
      cache[n] = v
      return v
    }
    // var num = fib(5)
    // console.log(num)
    for (let i = 0; i <= 9; i++) {
      console.log(fib(i))
    }
    console.log(cache) // {2: 2, 3: 3, 4: 5, 5: 8, 6: 13, 7: 21, 8: 34, 9: 55}

<think>嗯,用户让我输出斐波那契数列50。首先,我得确认斐波那契数列的定义,通常是从0和1开始,后面每一都是之和。不过有时候会从1和1开始,所以可能需要确认一下用户的需求,但一般来说,编程题里常见的应该是从0开始的。 接下来要考虑的是如何高效生成50。递归方法肯定不行,因为递归的时间复杂度太高,计算到第50会非常慢。应该用迭代的方法,或者更高效的方式。比如用循环来逐个计算每一,保存的值,这样时间复杂度是线性的,O(n),应该没问题。 然后,用户可能关心的是代码的简洁性和效率。Python的话,可以用生成器或者列表来存储结果。不过生成50,用列表可能更直观。另外,处理大的问题,斐波那契数列增长很快,第50已经很大了,但Python的整可以处理很大的,不用担心溢出。 然后,代码结构方面。可能需要初始化两个,然后循环从第三开始计算,直到第50。注意循环的次,比如已经有了,循环48次就够了,因为总共要50。或者用range的参来控制次,比如range(2, 50)然后计算到索引49。 另外,输出格式可能需要每个用逗号分隔,或者换行显示。但用户只是要求输出50,可能不需要特别的格式化,直接打印列表即可。不过如果太多,直接打印全部可能会显示不全,可以考虑循环打印每一。 还有考虑代码的简洁性,比如用元组赋值来更新a和b的值,避免使用临时变量。例如a, b = b, a + b,这样既简洁又高效。 可能还需要测一下代码是否正确,比如是否正确,0,1,1,2,3,5等等。另外检查循环次是否正确,是否生成了正好50。 用户有没有其他需求呢?比如内存使用,生成50的话,用列表存储没问题,内存占用不大。或者是否需要考虑空间复杂度,但50对于现代计算机来说微不足道。 有没有更Pythonic的法?比如使用列表推导式,不过因为每一都依赖,列表推导式可能不太方便,还是用循环更直接。 最后,可能需要给用户解释一下代码的思路,以及斐波那契数列的特性,比如指级增长,或者应用场景,但用户可能只需要代码和简要说明。所以回答的结构应该是先给出代码,然后解释原理,可能还有注意事,比如从0开始等。 检查一下代码有没有错误,比如初始是否正确,循环次是否正确,是否生成了50个元素。例如,初始化列表为[0,1],然后循环48次,添加48个元素,总共50个。或者使用动态计算,每次计算下一并添加到列表,直到长度达到50。 可能还需要考虑用户是否希望从0开始,比如是0和1,还是1和1。如果用户没有特别说明,可能需要注明,这里采用的是从0和1开始的版本。 总结下来,代码应该用循环迭代生成,确保高效和正确,输出50,并且解释清楚实现方法和注意事。</think>**Python极简实现(时间复杂度$O(n)$):** ```python a, b = 0, 1 for _ in range(50): print(a, end=' ') a, b = b, a + b ``` **原理说明:** 1. 使用元组解包操作`a, b = b, a+b`同步更新数列 2. 直接输出避免存储全部据(内存占用$O(1)$) 3. 循环50次输出50 **学特性补充:** - 第50值为$F(49)=7,778,742,049$(从$F(0)=0$开始计) - 通公式:$F(n)=\frac{\phi^n-\psi^n}{\sqrt{5}}$,其中$\phi=\frac{1+\sqrt{5}}{2}$(黄金分割比) **内存优化版(生成器实现):** ```python def fib(): a, b = 0, 1 while True: yield a a, b = b, a + b print(*[next(fib()) for _ in range(50)]) ``` **注意事:** 1. 数列增长速度符合指增长$O(\phi^n)$ 2. 第50值超过$7\times10^9$,若使用32位整型会溢出 3. Python自动支持大整运算,无需特殊处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值