首页 > 其他分享 >力扣-509. 斐波那契数 70. 爬楼梯

力扣-509. 斐波那契数 70. 爬楼梯

时间:2023-06-04 11:55:05浏览次数:43  
标签:契数 frac 复杂度 sqrt 斐波 509 bigg

参考:https://leetcode.cn/problems/climbing-stairs/solutions/286022/pa-lou-ti-by-leetcode-solution/
更详细的动态规划题解:https://leetcode.cn/problems/fibonacci-number/solutions/8330/dong-tai-gui-hua-tao-lu-xiang-jie-by-labuladong/

题目:

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。

方法一:动态规划
斐波那契数的边界条件是 F(0)=0 和 F(1)=1。当 n>1 时,每一项的和都等于前两项的和,因此有如下递推关系:

F(n)=F(n−1)+F(n−2)

由于斐波那契数存在递推关系,因此可以使用动态规划求解。动态规划的状态转移方程即为上述递推关系,边界条件为 F(0) 和 F(1)。

根据状态转移方程和边界条件,可以得到时间复杂度和空间复杂度都是 O(n) 的实现。由于 F(n) 只和 F(n−1) 与 F(n−2) 有关,因此可以使用「滚动数组思想」把空间复杂度优化成 O(1)。

class Solution {
public:
    int fib(int n) {
        int a=0,b=1,c;
        if(n<2)return n;
        for(int i=2;i<=n;i++){
            c=a+b;
            a=b;b=c;
        }
        return c;
    }
};

方法二:矩阵快速幂
还没弄懂

方法三:通项公式
斐波那契数 F(n)F(n)F(n) 是齐次线性递推,根据递推方程 F(n)=F(n−1)+F(n−2),可以写出这样的特征方程:

\[x^2=x+1 \]

求得\(x_1=\frac{1+\sqrt{5}}{2}\),\(x_2=\frac{1-\sqrt{5}}{2}\)。设通解为\(F(n)=c_1x_1^n+c_2x_2^n\),代入初始条件\(F(0)=0\),\(F(1)=1\),得\(c_1=\frac{1}{\sqrt{5}}\),\(c_2=-\frac{1}{\sqrt{5}}\)。
因此斐波那契数的通项公式如下:

\[F(n)=\frac{1}{\sqrt{5}}\bigg[\bigg(\frac{1+\sqrt{5}}{2}\bigg)^2-\bigg(\frac{1-\sqrt{5}}{2}\bigg)^2\bigg] \]

得到通项公式之后,就可以通过公式直接求解第 n 项。

class Solution {
public:
    int fib(int n) {
        double sqrt5 = sqrt(5);
        double fibN = pow((1 + sqrt5) / 2, n) - pow((1 - sqrt5) / 2, n);
        return round(fibN / sqrt5);
    }
};

复杂度分析
代码中使用的 pow 函数的时空复杂度与 CPU 支持的指令集相关,这里不深入分析。

总结
这里形成的数列正好是斐波那契数列,答案要求的 f(n) 即是斐波那契数列的第 n 项(下标从 0 开始)。我们来总结一下斐波那契数列第 n 项的求解方法:

  • n 比较小的时候,可以直接使用过递归法求解,不做任何记忆化操作,时间复杂度是 \(O(2^n)\),存在很多冗余计算。
  • 一般情况下,我们使用「记忆化搜索」或者「迭代」的方法,实现这个转移方程,时间复杂度和空间复杂度都可以做到 O(n)。
  • 为了优化空间复杂度,我们可以不用保存 f(x−2) 之前的项,我们只用三个变量来维护 f(x)、f(x−1) 和 f(x−2),你可以理解成是把「滚动数组思想」应用在了动态规划中,也可以理解成是一种递推,这样把空间复杂度优化到了 O(1)。
  • 随着 nnn 的不断增大 O(n) 可能已经不能满足我们的需要了,我们可以用「矩阵快速幂」的方法把算法加速到 O(log⁡n)。
  • 我们也可以把 n 代入斐波那契数列的通项公式计算结果,但是如果我们用浮点数计算来实现,可能会产生精度误差。

标签:契数,frac,复杂度,sqrt,斐波,509,bigg
From: https://www.cnblogs.com/kuuhaku/p/17455337.html

相关文章

  • qoj#5098
    兔队线段树题。记\(\{a_i\}\)的前缀和为\(\{S_i\}\),记距离\(i\)位置最近的颜色相同位置为\(pre_i\),那当钦定某个点\(i\)为右端点时,左端点最小可以为\(\max\limits_{1\lej\lei}\{pre_j\}+1\)。考虑对于线段树上每个结点\(p\),记其对应的区间为\([l_p,r_p]\),中点......
  • 斐波那契数列:2.迭代法
    斐波那契数列:2.迭代法#include<stdio.h>intfib(intm){if(m==1||m==2){return1;}inta=1,b=1,aw=0;while(m>=2){aw=aw+a;a=b;b=aw;m=m-1;}returnaw;}intmain(){intn;scanf("%d",&n);p......
  • 斐波那契数列:1.递归法
    斐波那契数列:1.递归法#include<stdio.h>intfib(intm){if(m>=3){returnfib(m-1)+fib(m-2);}else{return1;}}intmain(){intn;scanf("%d",&n);printf("%d",fib(n));return0;}......
  • 斐波那契数列:2.数组
    斐波那契数列:2.数组#include<stdio.h>intfib(intm){inti;inta[100]={0,1,1};for(i=2;i<=m;i++){a[i]=a[i-1]+a[i-2];}returna[m];}intmain(){intn;scanf("%d",&n);printf("%d",fib(n));return0......
  • 使用 Python 计算斐波那契数列
    斐波那契数列是一个经典的数学序列,其每个数字是前两个数字之和。本篇博客将展示如何使用Python编程语言计算斐波那契数列。通过实际代码示例,读者将能够理解斐波那契数列的概念以及如何在Python中实现。文章内容:斐波那契数列简介介绍斐波那契数列的定义和特点。解释斐波那契数列......
  • docker login harbor x509: certificate signed by unknown authority
    前言dockerloginharborx509:certificatesignedbyunknownauthority解决打开/etc/docker/daemon.json,如果没有这个文件新增即可vim/etc/docker/daemon.json加入insecure-registries{"insecure-registries":["harbor.xxxx.com:1111"]}重启dockersudo......
  • K8S异常之Unable to connect to the server: x509: certificate has expired or is n
    一、问题:k8s证书过期[root@nb001~]#kubectlgetnodeUnabletoconnecttotheserver:x509:certificatehasexpiredorisnotyetvalid:currenttime2022-12-10T10:26:21+08:00isafter2022-12-10T01:55:52Z 二、解决方案:2.1处理步骤#备份kubernetes配置......
  • 浅谈斐波那契数列和卡特兰数
    斐波那契数列斐波那契数列是我们较为熟悉的一类数列了,在学习递归和递推的时候我们就已经能求解\(n\)较小的情况了;斐波那契数列的定义如下:\[\left\{\begin{matrix}F_{n}=0&n=0\\F_{n}=1&n=1\\F_{n}=F_{n-1}+F_{n-2}&n\ge2\end{matrix}\right.\]卢卡斯数列卢卡斯数列......
  • 蓝桥杯2022年第十三届决赛真题-斐波那契数组(动态规划)
    题目描述如果数组A=(a0,a1,···,an−1)满足以下条件,就说它是一个斐波那契数组:n≥2;a0=a1;对于所有的i(i≥2),都满足ai=ai−1+ai−2。现在,给出一个数组A,你可以执行任意次修改,每次修改将数组中的某个位置的元素修改为一个大于0的整数。请问最......
  • 斐波那契数列的实现
    斐波那契数列(Fibonaccisequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(LeonardodaFibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(......