首页 > 编程语言 >算法系列:斐波那契数列问题

算法系列:斐波那契数列问题

时间:2022-11-15 23:44:50浏览次数:62  
标签:map return 数列 递归 int else 斐波 那契

问题描述:

  假设有个楼梯,每次只能走3步或者5步,问到达第N节会有几种组合?

思路分析:

  这个问题需要反过来思考才能比较容易的找到规律。总共有N级台阶,因为每次要么上3阶要么上5阶,因此对于第N级台阶来说,它的前一步要么是在N-3阶处要么是在N-5阶处。在N-3阶处时上3阶到N级台阶,在N-5阶处时上5级到N级台阶。因此,可以用公式表示为f(n)=f(n-3)+f(n-5),这就变成了一个典型的递归了。像这种公式,在数列中有一个比较著名的数列叫做“斐波那契数列”,当然这里是3和5可以看做是一种变形的“斐波那契数列”;如果把3和5变成1/2就是完美的斐波那契数列了;

  补充:斐波那契数列是满足F(n)=F(n-1)+F(n-2) 的数列

  好了既然分析出规律了,那么我们用代码实现以下

方法一:递归实现

    时间复杂度:O(!n) 

    public static int countStep(int n) {
        if (n < 3) {   //当n小于最小阶数时,没有可能的方案
            return 0;
        } else if (n == 3) {   //当前值等于3时.只有一种可能
            return 1;
        } else if (n > 3 && n < 5) {//当前值大于3并且者小于5时.没有可能的方案
            return 0;
        } else if (n == 5) {  //当n==5时只有一种可能
            return 1;
        } else {  //n>5时,采用递归的方式进行计算
            return countStep(n - 3) + countStep(n - 5);
        }
    }

方法二:动态规划

  方法一种的单纯递归的时间复杂度过高,我们可以将之前计算过的结果存放到map中,如果之后map中存在则直接获取;

    public static int climbStairs(int n, Map<Integer, Integer> map) {
        if (n < 3) {   //当n小于最小阶数时,没有可能的方案
            return 0;
        } else if (n == 3) {   //当前值等于3时.只有一种可能
            return 1;
        } else if (n > 3 && n < 5) {//当前值大于3并且者小于5时.没有可能的方案
            return 0;
        } else if (n == 5) {  //当n==5时只有一种可能
            return 1;
        } else if (map.containsKey(n)) {//若Map中已经存在之前的计算结果,则直接从map中获取
            return map.get(n);
        } else {  //n>5时,采用递归的方式进行计算
            int temp = climbStairs(n - 3, map) + climbStairs(n - 5, map);
            map.put(n, temp);
            return temp;
        }
    }

  上述动态规划在n比价小的时候并不能体现其优势,但当n较大时,就有可一避免出现多处的重复计算的情况,较少时间复杂度;

拓展思考:

  变形一:每次能走3阶、5阶、7阶时,有多少种可能?

    思路:F(n)=F(n-3)+F(n-5)+F(n-7)

  变形二:每次最多走M阶,问走到N阶有多少种可能?

    思路:F(n)=F(n-1)+F(n-2)+F(n-3)……F(n-m)

代码实现 

    public static int countM(int n, int m, Map<Integer, Integer> map) {
        int count = 0;
        if (n == 0) {
            return 1;
        }
        if (map.containsKey(n)) {
            return map.get(n);
        } else if (n >= m) {
            for (int i = 1; i <= m; i++) {
                count += countM(n - i, m, map);
            }
        } else {
            count += countM(n, n, map);
        }
        map.put(n, count);
        return count;
    }

 

总结:该算法是对菲波那切数列的应用,一般情况下,一旦能用数列的形式表示某种关系那么最先想到的就是递归。该题的难点是能够找到递归规律以及在递归中各种数值的划分。

 

参考链接:N级台阶,一次上1级或2级或3级或M级,总共有多少种走法

标签:map,return,数列,递归,int,else,斐波,那契
From: https://www.cnblogs.com/lsgspace/p/16894372.html

相关文章

  • 数据结构之动态规划 斐波那契数列&最长公共子序列
    $fib()$递归$fib(n)=fib(n-1)+fib(n-2):{0,1,1,2,3,5,8,……}$复杂度计算$T(0)=T(1)=1;T(n)=T(n-1)+T(n-2)+1,n>1$令$S(n)=\frac{[T(n)+1]}{2}$//这是要去掉......
  • 《程序员数学:斐波那契》—— 为什么不能用斐波那契散列,做数据库路由算法?
    作者:小傅哥博客:https://bugstack.cn源码:https://github.com/fuzhengwei/java-algorithms沉淀、分享、成长,让自己和他人都能有所收获!......
  • P1182 数列分段 Section II
    题干 记录为了练二分答案过程中发生了以下脑瘫错误1.加了两次最后一个数 2.这个是因为凑答案,还是对二分板子不熟属于是个二分答案的板子,记一下,代码如下其中有......
  • 算法题--斐波那契数列
    9要求时间限制:1秒空间限制:32768K题目描述大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39解题思路这道题可以直接用递归来解决,但......
  • LeetCode 665. 非递减数列
    classSolution{public:boolcheckPossibility(vector<int>&nums){intn=nums.size();for(inti=0;i<n-1;i++){intx=nums[i......
  • 斐波那契数列求第n项值
    斐波那契数列已知:斐波那契数列第n项是除前两项以外,第n-2与第n-1项的和:S(n)=S(n-2)+S(n-1)。优化前//优化前constn="";functiongetFibonacciSequenceItem......
  • 斐波那契dp
    21,斐波那契概念如果是dp,就同个子问题得到当前问题方程\[F[i]=F[i-1]+F[i-2]\]代码//优化版本classSolution{public:intFibonacci(intn){intfr......
  • 求第n个斐波那契数
    第一种:递归,效率低,运算慢。#include<stdio.h>#include<string.h>int fib(intn){if(n<=2)return 1;elsereturnfib(n-1)+fib(n-2);}int main(){int n=0;intret=0;sc......
  • linux 参数列表过大
    ref:https://blog.csdn.net/weixin_39972777/article/details/111103053在使用rm*命令删除文件的时候,会提示参数列表过大,此时我们可以使用如下方法:递归删除find......
  • OJ周赛第三场——最大和数列
    最大和数列 问题描述 给定一个长为m的序列b你需要构造出一个序列A满足:对于所有1≤i≤m,i在A中出现了bi次定义f(A) 的值如下:求满足条件的 f(A)的最大......