rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • Fibonacci 斐波那契

  • 算法定义
  • 算法思路
  • 算法复杂度
  • 应用场景
  • 优点与缺点
  • Java 实现及优化版本
  • 各版本优化说明
  • 资料

Fibonacci 斐波那契

算法定义

斐波那契(Fibonacci)数列是一个经典的数学序列,其定义为:

  • 第 0 项为 0,第 1 项为 1
  • 从第 2 项开始,每一项都等于前两项之和,即 F(n) = F(n-1) + F(n-2)

斐波那契算法是用于计算该序列中第 n 项的算法,其核心是通过不同策略实现上述递归关系,解决序列计算问题。

1 1 2 3 5 8 13 21 ...
 
fib 0 1 位置 = 1

fib(n) = fib(n-1) + fib(n-2)

斐波那契数列(fibonacci sequence)、重叠子问题(overlap sub-problem)

算法思路

斐波那契算法的核心是实现递推关系 F(n) = F(n-1) + F(n-2),不同实现方式的思路如下:

  1. 递归思路:直接通过函数自我调用计算,将大问题分解为小问题
  2. 递推思路:从初始项开始,迭代计算至目标项
  3. 矩阵快速幂思路:利用矩阵乘法的性质,通过快速幂优化计算
  4. 公式思路:使用通项公式直接计算(存在精度问题)

算法复杂度

实现方式时间复杂度空间复杂度
递归版O(2ⁿ)O(n)
基本递推版O(n)O(n)
优化递推版O(n)O(1)
矩阵快速幂版O(log n)O(1)
公式版O(1)O(1)

所有实现的最坏、最好和平均时间复杂度一致,因为计算逻辑不受输入数据分布影响。

应用场景

  • 数学问题(黄金分割、数列研究)
  • 算法优化(斐波那契查找、动态规划基础案例)
  • 生物领域(种群增长模型)
  • 金融分析(复利计算模型)
  • 计算机科学(递归与迭代教学、算法复杂度分析案例)

优点与缺点

不同实现方式的优缺点对比:

  • 递归版:
    • 优点:代码简洁,符合数学定义
    • 缺点:效率极低,存在大量重复计算,递归深度有限制
  • 递推版:
    • 优点:效率高,实现简单,无栈溢出风险
    • 缺点:需要遍历至目标项,不适合超大规模 n
  • 矩阵快速幂版:
    • 优点:时间复杂度低(O (log n)),适合超大 n
    • 缺点:实现复杂,理解门槛高
  • 公式版:
    • 优点:理论上可直接计算,时间复杂度 O (1)
    • 缺点:浮点数精度限制,无法计算大 n

Java 实现及优化版本

import java.math.BigInteger;

public class Fibonacci {
    
    // 1. 递归版(效率最低,仅作演示)
    public static long fibonacciRecursive(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("n不能为负数");
        }
        // 基线条件
        if (n == 0) return 0;
        if (n == 1) return 1;
        // 递归计算
        return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2);
    }
    
    // 2. 基本递推版(存储所有中间结果)
    public static long fibonacciIterativeBasic(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("n不能为负数");
        }
        if (n == 0) return 0;
        if (n == 1) return 1;
        
        // 存储所有中间结果
        long[] fib = new long[n + 1];
        fib[0] = 0;
        fib[1] = 1;
        
        for (int i = 2; i <= n; i++) {
            fib[i] = fib[i - 1] + fib[i - 2];
        }
        return fib[n];
    }
    
    // 3. 空间优化递推版(仅保留最近两项)
    public static long fibonacciIterativeOptimized(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("n不能为负数");
        }
        if (n == 0) return 0;
        if (n == 1) return 1;
        
        long prevPrev = 0; // F(n-2)
        long prev = 1;     // F(n-1)
        long current = 0;  // F(n)
        
        for (int i = 2; i <= n; i++) {
            current = prev + prevPrev;
            prevPrev = prev;
            prev = current;
        }
        return current;
    }
    
    // 4. 记忆化递归版(解决重复计算问题)
    public static long fibonacciMemoization(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("n不能为负数");
        }
        // 使用数组存储已计算结果
        long[] memo = new long[n + 1];
        for (int i = 0; i <= n; i++) {
            memo[i] = -1; // 初始化标记未计算
        }
        return fibonacciMemoHelper(n, memo);
    }
    
    private static long fibonacciMemoHelper(int n, long[] memo) {
        if (n == 0) return 0;
        if (n == 1) return 1;
        
        // 检查是否已计算
        if (memo[n] != -1) {
            return memo[n];
        }
        
        // 计算并存储结果
        memo[n] = fibonacciMemoHelper(n - 1, memo) + fibonacciMemoHelper(n - 2, memo);
        return memo[n];
    }
    
    // 5. 矩阵快速幂版(适合超大n,O(log n)时间)
    public static long fibonacciMatrix(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("n不能为负数");
        }
        if (n == 0) return 0;
        
        // 矩阵 [[1,1],[1,0]] 的n-1次方
        long[][] matrix = {{1, 1}, {1, 0}};
        matrix = matrixPower(matrix, n - 1);
        
        // 结果为矩阵[0][0]
        return matrix[0][0];
    }
    
    // 矩阵乘法
    private static long[][] matrixMultiply(long[][] a, long[][] b) {
        return new long[][] {
            {a[0][0] * b[0][0] + a[0][1] * b[1][0], 
             a[0][0] * b[0][1] + a[0][1] * b[1][1]},
            {a[1][0] * b[0][0] + a[1][1] * b[1][0], 
             a[1][0] * b[0][1] + a[1][1] * b[1][1]}
        };
    }
    
    // 矩阵快速幂(二分法)
    private static long[][] matrixPower(long[][] matrix, int power) {
        // 初始化为单位矩阵
        long[][] result = {{1, 0}, {0, 1}};
        
        while (power > 0) {
            if (power % 2 == 1) {
                result = matrixMultiply(result, matrix);
            }
            matrix = matrixMultiply(matrix, matrix);
            power /= 2;
        }
        return result;
    }
    
    // 6. 支持大整数的版本(解决long溢出问题)
    public static BigInteger fibonacciBigInteger(int n) {
        if (n < 0) {
            throw new IllegalArgumentException("n不能为负数");
        }
        if (n == 0) return BigInteger.ZERO;
        if (n == 1) return BigInteger.ONE;
        
        BigInteger prevPrev = BigInteger.ZERO;
        BigInteger prev = BigInteger.ONE;
        BigInteger current = BigInteger.ZERO;
        
        for (int i = 2; i <= n; i++) {
            current = prev.add(prevPrev);
            prevPrev = prev;
            prev = current;
        }
        return current;
    }
    
    public static void main(String[] args) {
        int n = 30;
        
        System.out.println("递归版 F(" + n + ") = " + fibonacciRecursive(n));
        System.out.println("基本递推版 F(" + n + ") = " + fibonacciIterativeBasic(n));
        System.out.println("优化递推版 F(" + n + ") = " + fibonacciIterativeOptimized(n));
        System.out.println("记忆化递归版 F(" + n + ") = " + fibonacciMemoization(n));
        System.out.println("矩阵快速幂版 F(" + n + ") = " + fibonacciMatrix(n));
        System.out.println("大整数版 F(100) = " + fibonacciBigInteger(100));
    }
}

各版本优化说明

  1. 递归版: 直接实现数学定义,代码最简单但效率极低,存在大量重复计算(如计算 F (5) 需重复计算 F (3)、F (2) 等),仅适合理解原理,不适合实际应用。
  2. 基本递推版: 通过迭代计算,避免重复计算,时间复杂度优化至 O (n),但需存储所有中间结果,空间复杂度 O (n)。
  3. 空间优化递推版: 仅保留最近两项结果,将空间复杂度从 O (n) 降至 O (1),是实际应用中的首选方案,平衡了效率和实现复杂度。
  4. 记忆化递归版: 通过缓存已计算结果解决递归版的重复计算问题,时间复杂度 O (n),空间复杂度 O (n),适合需要递归形式的场景。
  5. 矩阵快速幂版: 利用矩阵乘法性质和快速幂算法,将时间复杂度降至 O (log n),适合计算超大 n 值(如 n > 10⁶),但实现较复杂。
  6. 大整数版: 使用BigInteger解决 long 类型的溢出问题,可计算非常大的斐波那契数(如 n=10000),适合需要高精度结果的场景。

斐波那契算法是算法设计的经典案例,其不同实现方式展示了递归、迭代、动态规划、矩阵运算等多种算法思想,是理解算法优化过程的绝佳范例。在实际开发中,应根据 n 的大小和精度要求选择合适的实现方式。

资料

从Fibonacci函数的四种实现聊起

最近更新:: 2025/9/27 00:43
Contributors: luokaiwen