【数据结构】斐波那契数列优化

斐波那契数列简介

  • 第一个月:有 1 对兔子①
  • 第二个月:兔子①进入成熟期,还是 1 对
  • 第三个月:兔子①生了一对兔子②,第三个月就有 2 对兔子
  • 第四个月:兔子①生了一对兔子③,兔子②进入成熟期,这个月有 3 对兔子
  • 第五个月:兔子①生了一对兔子④,兔子②生了一对兔子⑤,兔子③进入成熟期,这个月有 5 对兔子
  • 第六个月:兔子①生了一对兔子⑥,兔子②生了一对兔子⑦,兔子③生了一对兔子⑧,兔子④进入成熟期,兔子⑤进入成熟期,这个月二有 8 对兔子

公式

想到斐波那契数列(兔子数列)就很容易想到递归算法

代码示例

long long Fib(int n) {
    if (n < 0)  return -1;

    if (n == 1 || n == 2) return 1;

    return Fib(n - 1) + Fib(n - 2);
}

递归算法写起来比较简单,但当 n 较大时,时间复杂度太高了(重复运算了很多数据)。

所以这里为了避免这种爆炸式的增加,运用规律,从第三项开始,后一项等于前两项之和。

代码实例

long long Fib(int n) {
    long long a = 1, b = 1, c = 0;

    if (n <= 0) return -1;

    if (n == 1 || n == 2) return 1;

    if (n > 2) {
        for (int i = 3; i <= n; ++i) {
            c = a + b;
            a = b;
            b = c;
        }
        return c;
    }
}
  • 循环里的 a = b; b = c; 是什么意思 ?

这个方法通过更新值的方式不断往后计算,节省了空间和时间,参考下图:

下面还有一种方式,与上面的方式相似,但使用数组进行存储数据,访问数据的前两个数,将他们加起来,得到当前值。

代码示例

long long Fib(int n) {
    long long temp = 0;
    long long* a = new long long[n + 1];

    a[1] = a[2] = 1;

    if (n <= 0) {
        return -1;
    }
    else {
        for (int i = 3; i <= n; ++i) {
            a[i] = a[i - 1] + a[i - 2];
        }
        temp = a[n];
    }
    delete[] a; 
    return temp;
}
  • 创建一个 n + 1 大小的数组,为什么是 n + 1 ?

前两个数据 1 是确定的,n 为 1 时,就创建两个空间,防止下面 a[2] 越界,当然也可以对 n 进行分析判断。

  • 临时变量 temp 的作用是什么 ?

temp 保存 a[n] 的值,是为了能在函数内销毁 new 出来的 a 空间(堆区空间)。

  • for 循环条件怎么确定的?

可以从最简单的 3 开始理解,当 n == 3 时这个循环只能执行一次,将 i 的初始值定为 3 ,判断条件为 i <= n,让 i 递增,而数组要通过下标的方式访问,可以写成 i = (i - 1) + (i - 2),随着 i 增加数据也不断往后移动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值