• 第十题:斐波那契数列


    大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。

    n<=39

    难度:⭐⭐⭐⭐

    关键:不能用递归,时间复杂度会以n的指数方式增长,导致stackoverflow。要用循环,为了计算量不大,要自下而上的循环,将运算结果存在中间变量中,这样就是O(n),以一定的空间代价避免代价更大的重复计算的栈空间浪费。

    思路:从2开始。f(2)=f(1)+f(0)...one=1,two=0,for(;;){result=one+two;one=result;two=one}

    其他:青蛙跳台阶(普通+变态版),矩形覆盖。运用了数学建模的分类思想。

    关于动态规划三个条件:最优子结构、无后效性、子问题重叠。

    我的。

    class Solution {
    public:
        int Fibonacci(int n) {
            //n<2时
            
            if(n<0) throw exception();
            else if(n<2) return n;
            else
            {
                int result=0;
                int first=1;
                int second=0; 
                for(int i=1;i<n;i++)
                {
                    result=first+second;
                    second=first;
                    first=result;
                }
                return result;
            }
    
        }
    };

     c++动态规划版

    class Solution {
    public:
        int Fibonacci(int n) {
            int f = 0, g = 1;
            while(n--) {
                g += f;
                f = g - f;
            }
            return f;
        }
    };
    

    python 。以数组的方式。

    # -*- coding:utf-8 -*-
    class Solution:
        def Fibonacci(self, n):
            # write code here
            res=[0,1,1,2]
            while len(res)<=n:
                res.append(res[-1]+res[-2])
            return res[n]

     其他题目 

    青蛙跳台阶

    class Solution {
    public:
        int jumpFloor(int number) {
            if(number<=0) throw exception();
            if(number<=2)
                return number;
            else
            {
                //f(3)=f(2)+f(1)
                int one=2;
                int two=1;
                int result=3;
                for(int i=2;i<number;i++)
                {
                    result=one+two;
                    two=one;
                    one=result;
                }
                return result;
            }
            
        }
    };

    python

    # -*- coding:utf-8 -*-
    class Solution:
        def jumpFloor(self, n):
            # write code here
            res=[1,1,2]
            while len(res)<=n:
                res.append(res[-1]+res[-2])
            return res[n]

    青蛙跳台阶变态版

    一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

    关于本题,前提是n个台阶会有一次n阶的跳法。分析如下:

    f(1) = 1

    f(2) = f(2-1) + f(2-2)         //f(2-2) 表示2阶一次跳2阶的次数。

    f(3) = f(3-1) + f(3-2) + f(3-3) 

    ...

    f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n-(n-1)) + f(n-n) 

    说明: 

    1)这里的f(n) 代表的是n个台阶有一次1,2,...n阶的 跳法数。

    2)n = 1时,只有1种跳法,f(1) = 1

    3) n = 2时,会有两个跳得方式,一次1阶或者2阶,这回归到了问题(1) ,f(2) = f(2-1) + f(2-2) 

    4) n = 3时,会有三种跳得方式,1阶、2阶、3阶,

        那么就是第一次跳出1阶后面剩下:f(3-1);第一次跳出2阶,剩下f(3-2);第一次3阶,那么剩下f(3-3)

        因此结论是f(3) = f(3-1)+f(3-2)+f(3-3)

    5) n = n时,会有n中跳的方式,1阶、2阶...n阶,得出结论:

        f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) => f(0) + f(1) + f(2) + f(3) + ... + f(n-1)

        

    6) 由以上已经是一种结论,但是为了简单,我们可以继续简化:

        f(n-1) = f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-1) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2)

        f(n) = f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) = f(n-1) + f(n-1)

        可以得出:

        f(n) = 2*f(n-1)

        

    7) 得出最终结论,在n阶台阶,一次有1、2、...n阶的跳的方式时,总得跳法为:

                  | 1       ,(n=0 ) 

    f(n) =     | 1       ,(n=1 )

                  | 2*f(n-1),(n>=2)

    class Solution {
    public:
        int jumpFloorII(int number) {
            // f(n) = 2*f(n-1)
            if (number <= 0) {
                    return -1;
                } else if (number == 1) {
                    return 1;
                } else {
                    return 2 * jumpFloorII(number - 1);
                }
        }
    };

    python

    # -*- coding:utf-8 -*-
    class Solution:
        def jumpFloorII(self, number):
            # write code here
            a=[1,2,4,8]
            while(len(a)<number):
                a.append(a[-1]*2)
            return a[number-1]

    小矩形覆盖大矩形

    class Solution {
    public:
        int rectCover(int number) {
            if(number<=2) return number;
            else
            {
                //f(3)=f(2)+f(1)
                //f(4)=f(3)+f(2)
                int one=2;
                int two=1;
                int result=3;
                for(int i=2;i<number;i++)//3
                {
                    result=one+two;
                    two=one;
                    one=result;
                }
                return result;
            }
        }
    };

    python

    # -*- coding:utf-8 -*-
    class Solution:
        def rectCover(self, number):
            # write code here
            a=[0,1,2,3]
            while(len(a)<=number):
                a.append(a[-1]+a[-2])
            return a[number]
  • 相关阅读:
    arcgis api 3.x for js 入门开发系列八聚合效果(附源码下载)
    arcgis api 3.x for js 入门开发系列七图层控制(附源码下载)
    arcgis api 3.x for js 入门开发系列六地图分屏对比(附源码下载)
    arcgis api 3.x for js 入门开发系列五地图态势标绘(附源码下载)
    arcgis api 3.x for js 入门开发系列四地图查询(附源码下载)
    Java里面获取当前服务器的IP地址
    Flutter at Google I/O 2018
    Modbus RTU 协议使用汇总
    plsql 创建表空间、用户、赋予权限
    Oracle:ODP.NET Managed 小试牛刀
  • 原文地址:https://www.cnblogs.com/lightmare/p/10434835.html
Copyright © 2020-2023  润新知