斐波那契数列--别样的解法--O(N)

简介: 在使用递归来求斐波那契数列时,可以发现,在这个过程中我们重复计算了一些值,如下图所示,很多值都计算过了,但在递归过程我们没有做其他的操作,所以就只能重复的算下去,那如果我们将计算的值保存下来,在进行递归时能够查找到计算过的值,就直接调用而不用重复的计算了

在使用递归来求斐波那契数列时,可以发现,在这个过程中我们重复计算了一些值,如下图所示,很多值都计算过了,但在递归过程我们没有做其他的操作,所以就只能重复的算下去,那如果我们将计算的值保存下来,在进行递归时能够查找到计算过的值,就直接调用而不用重复的计算了

先来看初级版

public class Test3 {
    public static void main(String[] args) {
        long startTime = System.nanoTime(); //获取开始时间
        int a = fib(20);
        System.out.println(a);
        long endTime = System.nanoTime(); //获取结束时间
        System.out.println("time:" + (endTime - startTime) + "ns"); //输出程序运行时间
    }
    private static Integer fib(int n){
        if (n==0)return 0;
        if (n==1||n==2)return 1;
        return fib(n-1)+fib(n-2);
    }
}

然后测个速,我这里用的纳秒

进阶版

import java.util.*;
public class Test1 {
    public static void main(String[] args) {
        long startTime = System.nanoTime(); //获取开始时间
        int a = f(20);
        System.out.println(a);
        long endTime = System.nanoTime(); //获取结束时间
        System.out.println("time:" + (endTime - startTime) + "ns"); //输出程序运行时间
    }
    private static Integer f(int n){
        if (n==0)return 0;
        int[] b = new int[n+1];
        return save(b,n);
    }
    private static Integer save(int[] a,int n){
        if (n ==1||n==2)return 1;
        if (a[n]!=0)return a[n];
        a[n] = save(a, n-1)+save(a,n-2);
        return a[n];
    }
}

可以看到,速度整整快了三倍多,这只是简单的一个比较,我们再来算一下时间复杂度。

A:

因为我们将每一次计算的结果都保存在数组中,所以不存在重复的计算,输入的值为N时,所要解决的问题也就是N个,每个问题所需的时间为O(1),总的时间复杂度也就是O(N)。相比纯递归根本不是一个级别的差异。

相关文章
|
机器学习/深度学习 PyTorch 算法框架/工具
Pytorch CIFAR10图像分类 Swin Transformer篇(一)
Pytorch CIFAR10图像分类 Swin Transformer篇(一)
|
Linux Shell
在Linux中如何一次性运行多个命令?
在Linux中如何一次性运行多个命令?
909 0
|
存储 缓存 固态存储
优化Elasticsearch 硬件配置
优化Elasticsearch 硬件配置
520 5
|
12月前
|
设计模式 测试技术
《怎样实现代码的可维护性和可扩展性》
实现代码的可维护性和可扩展性,需关注命名与注释、遵循编程规范、模块化设计、应用设计模式、编写单元测试、使用版本控制、文档化及定期重构等方面。这些措施有助于提升代码质量,促进团队协作,确保项目长期健康发展。
369 12
|
SQL 关系型数据库 MySQL
【赵渝强老师】MySQL的全量日志文件
MySQL全量日志记录所有操作的SQL语句,默认禁用。启用后,可通过`show variables like %general_log%检查状态,使用`set global general_log=ON`临时开启,执行查询并查看日志文件以追踪SQL执行详情。
203 4
|
12月前
|
人工智能 调度 算法框架/工具
【AI系统】计算图的调度与执行
深度学习训练过程涉及前向计算、计算损失及更新权重参数。AI框架通过计算图统一表示训练过程,算子作为计算图的节点,由后端硬件高效执行。计算图调度包括算子间的调度、并发调度和异构调度,确保计算资源的有效利用。图执行模式分为单算子执行、整图下沉执行和图切分多设备执行,适应不同场景需求。以PyTorch为例,其算子执行通过两次调度选择合适的Kernel进行张量操作,并支持自动求导。
518 5
|
jenkins 测试技术 持续交付
基于Jenkins+Python+Ubuntu+Docker的接口/UI自动化测试环境部署详细过程
基于Jenkins+Python+Ubuntu+Docker的接口/UI自动化测试环境部署详细过程
1092 1
|
JavaScript Java 测试技术
基于SpringBoot+Vue的城市公交调度系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue的城市公交调度系统的详细设计和实现(源码+lw+部署文档+讲解等)
184 5
|
运维 安全 Devops
什么是安全左移,如何实现安全左移
传统软件开发面临安全挑战,如意识缺失、代码漏洞、第三方组件风险、配置管理问题及应对新型攻击能力不足。为改善现状,需采取安全左移策略,将安全措施提前至开发早期,与SDL结合,确保安全贯穿SDLC始终。安全左移面临计划制定、责任转移、工具选择等挑战,需通过规划、培训和选用合适工具应对。DevSecOps模式进一步将安全融入DevOps,提升开发效率和软件安全性,实现开发、安全和运维的协同。SDL与DevSecOps相辅相成,前者注重安全过程,后者强调安全文化与自动化。
861 1
什么是安全左移,如何实现安全左移
|
Linux 应用服务中间件 nginx
Docker 大势已去,Podman 即将崛起……
Docker 大势已去,Podman 即将崛起……
1650 0
Docker 大势已去,Podman 即将崛起……