算法 数据结构 斐波那契数列 递归实现斐波那契数列 斐波那契递归的优化 斐波那契数列递归求解 多路递归实现 斐波那契算法系列 数据结构(十一)

news2025/1/19 8:25:21

1. 什么是斐波那契数列:

  • 之前的例子是每个递归函数只包含一个自身的调用,这称之为 single recursion

  • 如果每个递归函数例包含多个自身调用,称之为 multi recursion

递推关系

f(n) = \begin{cases} 0 & n=0 \\ 1 & n=1 \\ f(n-1) + f(n-2) & n>1 \end{cases}

下面的表格列出了数列的前几项

F0F1F2F3F4F5F6F7F8F9F10F11F12F13
01123581321345589144233

多路递归斐波那契代码实现1:

package com.nami.algorithm.study.day07;

/**
 * beyond u self and trust u self.
 *
 * @Author: lbc
 * @Date: 2023-09-06 9:29
 * @email: 594599620@qq.com
 * @Description: keep coding
 */
public class Fibonacci {

    /**
     * 出现问题的,计算 n= 88 根本算不出来。多路递归一直在循环里面了。出不来 --!
     * @param n
     * @return
     */
    public static int calculate(int n) {
        if (n == 0) {
            return 0;
        }
        if (n == 1) {
            return 1;
        }
        int f1 = calculate(n - 1);
        int f2 = calculate(n - 2);
        return f1 + f2;
    }


    public static void main(String[] args) {
        // 时间复杂度: 2*f(n+1) -1
        // E(1.618N次方)
        System.out.println(calculate(88));
    }

}

  非递归实现2 --- LeetCode 70. 爬楼梯 计算爬楼梯共计多少种方法可达_不努力就种地~的博客-CSDN博客

  之前写的爬楼梯解决方案:

public static  int climbStairs(int n) {
        int[] dp = new int[n + 1];
        dp[0] = 1;
        dp[1] = 1;
        for(int i = 2; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }

这种方法直接用数组去存储前面计算的值,不用重复计算。没有出现上面n=88出现的计算缓慢问题

递归优化方案:

                       使用数组,存储之前计算的数据,减少计算次数。妙哉

package com.nami.algorithm.study.day07;

import java.util.Arrays;

/**
 * beyond u self and trust u self.
 *
 * @Author: lbc
 * @Date: 2023-09-06 9:29
 * @email: 594599620@qq.com
 * @Description: keep coding
 */
public class FastFibonacci {

    /**
     * 出现问题的,计算 n= 100000
     * 出现异常 StackOverflowError
     * 方法层级太深,会导致栈溢出
     *
     * @param n
     * @return
     */
    public static int calculate(int n) {
        // 初始化缓存
        // ==>记忆法
        // 空间换时间
        int[] cache = new int[n + 1];

        // 填充-1 标识未该值为计算
        Arrays.fill(cache, -1);
        cache[0] = 0;
        cache[1] = 1;
        return fibonacci(n, cache);
    }

    /**
     * 时间复杂度: O(n)
     * 增加额外空间成本
     *
     * @param n
     * @param cache
     * @return
     */
    private static int fibonacci(int n, int[] cache) {
        if (cache[n] != -1) {
            return cache[n];
        }
        int f1 = fibonacci(n - 1, cache);
        int f2 = fibonacci(n - 2, cache);
        cache[n] = f1 + f2;
        return cache[n];
    }

    public static void main(String[] args) {
        // n=88也有问题,出现-值
        // -2092787285
        System.out.println(calculate(88));
    }

}

使用数组进行优化,也有一个问题,数组只有n-1, n-2两个值有用。对于计算之后,存储前面n-3的值没有了意义;
 

优化2 ==>尾递归:

                            尾递归(防止栈溢出) +  只取n-1, n-2的值流转

package com.nami.algorithm.study.day07;

/**
 * 尾递归 斐波那契数列
 * beyond u self and trust u self.
 *
 * @Author: lbc
 * @Date: 2023-09-06 9:29
 * @email: 594599620@qq.com
 * @Description: keep coding
 */
public class TailRecFibonacci {

    /**
     * @param n
     * @return
     */
    public static int calculate(int n) {
        return fibonacci(n, 0, 1);
    }

    private static int fibonacci(int n, int first, int second) {
        if (n == 0) {
            return first;
        }
        if (n == 1) {
            return second;
        }
        return fibonacci(n - 1, second, first + second);
    }

    public static void main(String[] args) {
        // n=47,出现-值
        // -1323752223
        // 18 3631 1903 + 11 3490 3170
        //    n= 46     +    n=45
        // int 最大值 21 4748 3647
        System.out.println(calculate(46));
    }

}

为什么斐波那契数列会出现负值

      当n=88时,结果等于负数。排查发现:当n=46是正常的,n=47时,前面两个值的相加已经超过了int最大值int.max_value= 21 4748 3647 所以出现负数

如何根本上解决爆栈问题

                                   递归转for or while循环解决问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/982856.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

空气传导耳机哪个牌子好?市面上热销火爆的气传导耳机推荐

​传统入耳式耳机佩戴着容易滑落&#xff0c;戴不稳&#xff0c;久戴耳朵酸痛等问题&#xff0c;气传导耳机的出现就避免了这些问题的发生&#xff0c;我来推荐几款市面上热销火爆且使用感不错的气传导耳机给到大家&#xff0c;来看看吧&#xff01; 推荐1&#xff1a;NANK南卡…

[ubuntu]给WSL子系统ubuntu安一个桌面环境

sudo apt install xorg sudo apt install xfce4 sudo apt install xrdp sudo sed -i s/port3389/port3390/g /etc/xrdp/xrdp.ini sudo echo xfce4-session >~/.xsession sudo service xrdp restart 查看自己ip地址&#xff1a; ifconfig 然后在windows上任务栏搜远程桌面 …

亚马逊鲲鹏系统全自动化功能有哪些

亚马逊鲲鹏系统可以批量注册亚马逊买家号、AI智能养号、自动绑定收货地址及支付卡、开通二步验证、自动添加购物车、自动购买、自动留评、评论点赞或举报、QA等。 下面就详细介绍一下一些比较常用的自动化功能&#xff1a; 1、全自动注册 想要注册买家号&#xff0c;那么需要…

自动化测试基础知识详解

前言 有颜色的标注主要是方便记忆&#xff0c;勾选出个人感觉的重点 块引用&#xff1a;大部分是便于理解的话&#xff0c;稍微看看就行&#xff0c;主要是和正常的文字进行区分的 1、什么是自动化测试 自动化测试是软件测试活动中一个重要分支和组成部分&#xff0c;随着软…

Leetcode128. 最长连续序列

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 题解&#…

java 版本企业招标投标管理系统源码+功能描述+tbms+及时准确+全程电子化

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…

WINGREEN 034STN1-01-300-R 传感器模块

WINGREEN 034STN1-01-300-R 是一种传感器模块&#xff0c;通常用于监测和采集各种环境或过程参数的数据。以下是这种类型的传感器模块通常可能具备的一般功能和特点&#xff1a; 传感器接口&#xff1a;模块通常配备用于连接不同类型传感器的接口&#xff0c;如温度传感器、湿度…

贝塞尔曲线的一些资料收集

一本免费的在线书籍&#xff0c;供你在非常需要了解如何处理贝塞尔相关的事情。 https://pomax.github.io/bezierinfo/zh-CN/index.html An algorithm to find bounding box of closed bezier curves? - Stack Overflow https://stackoverflow.com/questions/2587751/an-algo…

Linux 中的 cfdisk 命令及示例

cfdisk命令用于在磁盘设备上创建、删除和修改分区。它通过提供基于文本的“图形”界面来显示或操作磁盘分区表。 cfdisk /dev/sda 示例: 运行后您会收到如下提示:从列表中

YOLO目标检测——昏暗车辆数据集+已标注VOC格式标签下载分享

实际项目应用&#xff1a;昏暗车辆数据集在智能交通监控系统、驾驶辅助系统、城市安全监控、自动驾驶系统以及路况分析与规划等应用场景中具有广泛的应用潜力&#xff0c;可以提高车辆检测的准确性和效率&#xff0c;提升交通安全和城市管理水平。数据集说明&#xff1a;昏暗车…

leetcode 2. 两数相加(java)

两数相加 题目描述哨兵技巧代码演示&#xff1a; 递归算法专题 题目描述 难度 - 中等 leetcode 2. 两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&…

【LeetCode-中等题】90. 子集 II

文章目录 题目方法一&#xff1a;递归加回溯&#xff08;去重版&#xff09;![在这里插入图片描述](https://img-blog.csdnimg.cn/abc4e8d0e3f940fcbdcb072acf80734e.png) 题目 本题nums数组存在重复元素&#xff0c;所以本题会涉及一个去重操作&#xff1a; 子集无需去重版本&…

redis 高可用

Redis 高可用 在web服务器中&#xff0c;高可用是指服务器可以正常访问的时间&#xff0c;衡量的标准是在多长时间内可以提供正常服务&#xff08;99.9%、99.99%、99.999%等等&#xff09;。 但是在Redis语境中&#xff0c;高可用的含义似乎要宽泛一些&#xff0c;除了保证提供…

不用入耳就有好音质,南卡OE Pro 0压开放式耳机

从15年第一次接触无线耳机到如今大概用过二十多款无线耳机&#xff0c;用过最多的厂牌就是南卡&#xff0c;包括主、被动降噪和骨传导等品系的数个型号&#xff0c;见证了南卡产品从早期成长探索阶段到如今设计、工艺日臻完善且形成品系&#xff0c;对南卡的技术、工艺和设计愈…

03 卷积操作图片

一、均值滤波 # 卷积操作 # 输入图片. input, 必须是4维tensor(图片数量, 图片高度, 图片的宽度, 图片的通道数) # filters, 卷积核, 必须是4维的tensor(卷积核的高度和宽度, 输入图片的通道数, 卷积核的个数) # strides, 步长, 卷积核在图片的各个维度上的移动步长, (1, 1, 1,…

28.考试

Description 小学期马上就要结束了&#xff0c;为了检验大家的学习成果&#xff0c;老师进行了一次考试。然而小徐前两周半都忙于练习篮球&#xff0c;几乎没有学习&#xff0c;因此考试时很可能做不完所有题目。 但小徐仍然想要拿到尽可能高的分数&#xff0c;因此在做题时需要…

ODrive移植keil(二)—— ODrive的程序架构

目录 一、移植说明二、支持的驱动板三、程序架构说明3.1、从main开始3.2、TIM8更新中断3.3、AD转换的专题说明 ODrive、VESC和SimpleFOC 教程链接汇总&#xff1a;请点击 一、移植说明 上一节教程的移植主要体现在硬件上&#xff0c;软件改动很小并且仍然为VScode版本&#xff…

手写Spring:第16章-给代理对象的属性设置值

文章目录 一、目标&#xff1a;给代理对象的属性设置值二、设计&#xff1a;给代理对象的属性设置值三、实现&#xff1a;给代理对象的属性设置值3.1 工程结构3.2 在Bean生命周期中创建代理对象类图3.3 判断CGLIB对象3.4 迁移创建AOP代理方法3.4.1 实例化感知对象处理3.4.2 扫描…

自动化测试:selenium(完结篇)

一、元素操作方法 方法&#xff1a; 1、.send_keys() # 输入方法 2、.click() # 点击方法 3、.clear() # 清空方法注意&#xff1a;在输入方法之前一定要清空操作&#xff01;&#xff01; # 导包 from time import sleep from selenium import webdriver# 实例化浏览器 d…

教你如何在三秒内,将PPT转换成翻页的电子书

​大家好&#xff01;今天教大家一个非常实用的技巧 瞬间将你的PPT变身为炫酷的翻页电子书&#xff0c;这个方法非常简单&#xff0c;只需要几个操作步骤就能完成&#xff0c;让我们一起来看看吧&#xff01; 在转换之前肯定是需要一款工具的&#xff0c;可以试试FLBOOK在线制…