剑指offer--斐波那契数列及青蛙跳台阶问题(Java)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40244153/article/details/87730450

题目:写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。

思路:如果直接写递归函数,由于会出现很多重复计算,效率非常底,不采用。

public int Fibonacci1(int n) {
        if (n <= 0) return 0;
        if (n == 1) return 1;
        return Fibonacci1(n-1) + Fibonacci1(n - 2);
    }

要避免重复计算,采用从下往上计算,可以把计算过了的保存起来,下次要计算时就不必重复计算了:先由f(0)和f(1)计算f(2),再由f(1)和f(2)计算f(3)……以此类推就行了,计算第n个时,只要保存第n-1和第n-2项就可以了。

public int Fibonacci2(int n) {
        if (n <= 0) return 0;
        if (n == 1) return 1;
        int i=0;int j=1;
        int res=0;
        for(int x=2;x<=n;x++){
            res =  i+j;
            i=j;
            j=res;
        }
        return res;
    }

青蛙跳台阶问题

题目1:一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
     将跳法总数记为f(n),可以知道f(1)=1,f(2)=2。当n>2时,第一次跳1级的话,还有f(n-1)种跳法;第一次跳2级的话,还有f(n-2)种跳法,所以可以推得f(n)=f(n-1)+f(n-2),即为斐波那契数列。
题目2:一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法

解法1:
  当n=1时,f(1)=1。
  当n大于1时,归纳总结可知:跳上n级台阶,第一次跳1级的话,有f(n-1)种方法;第一次跳2级的话,有f(n-2)种方法……第一次跳n-1级的话,有f(1)种方法;直接跳n级的话,有1种方法,所以可以得到如下公式:
  f(n) = f(n-1)+f(n-2)+......f(1)+1  (n≥2
  f(n-1) = f(n-2)+f(n-3)+.....f(1)+1  (n>2)
  由上面两式相减可得,f(n)-f(n-1)=f(n-1),即f(n) = 2*f(n-1)  (n>2)
  最终结合f(1)和f(2),可以推得:f(n)=2^(n-1)
解法2:
    除了必须到达最后一级台阶,第1级到第n-1级台阶都可以有选择的跳,也就是说对于这n-1个台阶来说,每个台阶都有跳上和不跳上2种情况,所以一共有2^(n-1)种方法。

矩形覆盖问题
 题目:用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
  当n = 1时,有一种方法。
  当n = 2时,有两种方法。
  当n >= 3时,和斐波那契数列类似。第一步竖着放,有f(n-1)种方法;第一步横着放,有f(n-2)种方法。所以f(n)=f(n-1)+f(n-2)。

收获
  1.当遇到涉及n的问题时(类似青蛙跳台阶问题),不要紧张,可以进行归纳分析,特别注意f(n)与f(n-1)、f(n-2)等的关联,从而找出规律,进行合理建模。
  2.return (int)Math.pow(2,target-1);
    1) 转int类型
    2)pow不是power

猜你喜欢

转载自blog.csdn.net/weixin_40244153/article/details/87730450