zoukankan      html  css  js  c++  java
  • 7、斐波那契数列、跳台阶、变态跳台阶、矩形覆盖------------>剑指offer系列

    题目:斐波那契数列

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

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

    基本思路

    这道题在剑指offer中实际是当作递归的反例来说的。

    递归的本质是吧一个问题分解成两个或者多个小问题,如果多个小问题存在互相重叠的情况,那么就存在重复计算。

    f(n) = f(n-1) + f(n-2) 这种拆分使用递归是典型的存在重叠的情况,所以会造成非常多的重复计算。

    另外,每一次函数调用爱内存中都需要分配空间,每个进程的栈的容量是有限的,递归层次过多,就会造成栈溢出。

    递归是从最大数开始,不断拆解成小的数计算,如果不去考虑递归,我们只需要从小数开始算起,从底层不断往上累加就可以了,其实思路也很简单。

    代码

    function Fibonacci(n)
    {
        if(n<=1){
            return n;
        }
        let i = 1;
        let pre = 0;
        let current = 1;
        let result = 0;
        while(i++ < n){
            result = pre + current;
            pre = current;
            current = result;
        }
        return result;
    }

    题目:跳台阶

    一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

    基本思路

    找规律:

    跳三级台阶等于跳两级台阶的跳法+跳一级台阶的跳法。

    跳四级台阶等于跳三级台阶的跳法+跳二级台阶的跳法。

    明显也符合斐波那契数列的规律

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

    代码

    function jumpFloor(n)
    {
        if(n<=2){
            return n;
        }
        let i = 2;
        let pre = 1;
        let current = 2;
        let result = 0;
        while(i++ < n){
            result = pre + current;
            pre = current;
            current = result;
        }
        return result;
    }

    题目:变态跳台阶

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

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

    基本思路

    每个台阶都可以选择跳或者不跳,最后一个台阶必跳。

    每个台阶有两种选择,n个台阶有2的n次方种选择。

    所以一共有2的n-1次跳法。

    使用位运算

    代码

    function jumpFloorII(number)
    {
        return 1<<(--number);//Math.power(2,number-1)
    }

    题目:矩形覆盖

    我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
     

    基本思路

    假设为2*8,f(8)用第一个小矩形去覆盖左边有两种,竖着的之后,右边有f(7)中选择,当横着的时候,有f(6)中选择,所以f(8)=f(7)+f(6),也是斐波那契数列,n=1时只有一种,n=2时有两种,f(n)=f(n-1)+f(n-2)

    代码

    function rectCover(number)
    {
        // write code here
        if(number<0)
            return ;
         if(number<=2)
             return number;
        let [one,two]=[1,2];
        let temp;
        for(var i=3;i<=number;i++)
        {
            temp=one;
            one=two;
            two=temp+two;
        }
        return two;
    }
    

      

  • 相关阅读:
    用一个测试类简化排序算法时间复杂度的研究
    用斗地主的实例学会使用java Collections工具类
    数据结构:用实例分析ArrayList与LinkedList的读写性能
    用一个通俗易懂的例子彻底说清楚单例模式
    用自定义链式栈解决力扣括号匹配问题
    数据结构之链式队列的代码实现及有趣应用
    用非常硬核的JAVA序列化手段实现对象流的持久化保存
    SpringBoot整合SpringSecurity实现JWT认证
    六百字搞懂lambda
    判空我推荐StringUtils.isBlank
  • 原文地址:https://www.cnblogs.com/QianDingwei/p/10923738.html
Copyright © 2011-2022 走看看