当前位置: 首页 > article >正文

509. 斐波那契数

Problem: 509. 斐波那契数

文章目录

  • 思路
  • 解题方法
  • 复杂度
  • Code
    • 解法一 (暴力搜索)
    • 解法二 (记忆化搜索)
    • 解法三(动态规划)
    • 解法四(动态规划(空间O(1)))

思路

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给定 n ,请计算 F(n) 。

斐波那契数列是一个典型的递归问题,但是直接使用递归会导致大量的重复计算,因此我们可以使用动态规划的思想来优化。动态规划的核心思想是将大问题分解为小问题,然后从小问题开始解决,逐步解决大问题。

解题方法

1.暴力搜索:直接使用递归公式进行计算,但是这种方法存在大量的重复计算,时间复杂度高,不推荐使用。
2.记忆化搜索:在暴力搜索的基础上,使用一个数组来保存已经计算过的斐波那契数,避免重复计算。
3.动态规划:使用一个数组dp,其中dp[i]表示第i个斐波那契数,然后从小到大依次计算dp[i],最后返回dp[n]。
4.动态规划(空间O(1)):在动态规划的基础上,进一步优化空间复杂度。由于dp[i]只与dp[i-1]和dp[i-2]有关,因此我们只需要保存这两个状态,无需保存整个dp数组。

复杂度

时间复杂度:

时间复杂度: O ( n ) O(n) O(n),需要遍历一次序列。

空间复杂度:

空间复杂度: O ( 1 ) O(1) O(1),只需要常数个变量。

Code

解法一 (暴力搜索)

class Solution {
    public int fib(int n) {
        if(n == 0) {
            return 0;
        }
        if(n == 1) {
            return 1;
        }
        return fib(n - 1) + fib(n - 2);
    }
}

解法二 (记忆化搜索)

class Solution {
    public int fib(int n) {
        int[] arr = new int[n + 1];
        Arrays.fill(arr, -1);
        return f(n, arr);
    }
     public int f(int n, int[] arr) {
        if(n == 0) {
            return 0;
        }
        if(n == 1) {
            return 1;
        }
        // 命中缓存
        if(arr[n] != -1) {
            return arr[n];
        }
        int ans = f(n - 1, arr) + f(n - 2, arr);
        // 记录缓存
        arr[n] = ans;
        return ans;
    }
}

解法三(动态规划)

class Solution {
    public int fib(int n) {
        if (n == 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        int[] dp = new int[n + 1];
        dp[1] = 1;
        for(int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

解法四(动态规划(空间O(1)))

class Solution {
    public int fib(int n) {
        if (n == 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        int Lastlast = 0, Last = 1;
        for (int i = 2, cur; i <= n; i++) {
            cur = Lastlast + Last;
            Lastlast = Last;
            Last = cur;
        }
        return Last;
    }
}

http://www.kler.cn/a/232179.html

相关文章:

  • ollama+springboot ai+vue+elementUI整合
  • 15分钟学 Go 第 56 天:架构设计基本原则
  • 以太坊系地址衍生算法分层确定性生成逻辑
  • 二五、pxe自动装机
  • SQL Server Service Broker完整示例
  • 动态规划-背包问题——[模版]完全背包问题
  • C++ .h文件类的调用
  • 【多模态】27、Vary | 通过扩充图像词汇来提升多模态模型在细粒度感知任务(OCR等)上的效果
  • 面试高频知识点:2线程 2.1.5如何自定义实现一个线程池
  • C语言--------指针(1)
  • muduo库的模拟实现——TcpServer部分
  • 运维高级篇-分库分表(拆分策略详解)
  • 假期作业 7
  • 【嵌入式-传感器】从旋转编码器到学会看懂方波
  • 《动手学深度学习(PyTorch版)》笔记7.6
  • 复制和粘贴文本时剥离格式的5种方法(MacWindows)
  • c# Config 配置文件帮助类
  • 3.2 Verilog 时延
  • 一个基于 .NET 7 + Vue.js 的前后端分离的通用后台管理系统框架 - DncZeus
  • [Java][算法 哈希]Day 01---LeetCode 热题 100---01~03
  • 基于华为云欧拉操作系统(HCE OS)容器化部署传统应用(Redis+Postgresql+Git+SpringBoot+Nginx)
  • 【Network Management】AUTOSAR架构下CanNm User Data详解
  • echarts使用之地图(五)
  • 【几分钟】快速熟悉torch.save()、torch.load()、torch.nn.Module.load_state_dict()
  • ONLYOFFICE文档8.0新功能浅探
  • 软件测试学习笔记-测试用例的编写