难倒无数求职者的青蛙跳台阶问题及其拓展

222 阅读1分钟

青蛙跳台阶


引言

首先,我们写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项。

斐波那契(Fibonacci)数列定义如下:

在这里插入图片描述

代码实现

递归方式:
int fibnacci(int n){
    if (n==0){
        return 0;
    }
    if (n==1){
        return 1;
    }
    return fibnacci(n-1)+fibnacci(n-2);
}

非递归方式:
int Fibonacci(int n)
{
	int res[2] = {0 , 1};
	if(n < 2)
		return res[n];

	int fibMinusOne = 1;
	int fibMinusTwo = 0;
	int fibN=0;
	for(int i = 3 ; i <= n ; ++i)
	{
		fibN = fibMinusOne + fibMinusTwo;
		fibMinusTwo = fibMinusOne;
		fibMinusOne = fibN;
	}
	return fibN;
}

五大经典例题

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

状态:F(i):跳上i级台阶的方法数

F(1):一个台阶:1           		方法数:1

F(2):两个台阶:11    				   2
			  2
			  
F(3):三个台阶:111				   4
			  12          
			  21
			  3

F(4):四个台阶:1111				   8
			  112
			  121
			  211
			  22
			  13
			  31
			  4

状态转移方程推导: (F(0) = 1)

  • F(i) = F(i - 1)+F(i - 2)+F(i - 3)+…+F(0)
  • F(i - 1) = F(i - 2) + F(i - 3) +…+ F(0)
  • F(i) = F(i - 1) + F(i - 1) = 2i-1
  1. 限制青蛙一次最多只能跳上2级台阶:

F(i) = F(i - 1) + F(i - 2)

也可以这样理解:小青蛙想跳到第n阶台阶必须经过n-1或n-2阶台阶(小青蛙每次只能跳一阶或两阶),则问题转化为n阶台阶的跳法总数为n-1和n-2台阶的跳法总数之和,故表达式f(n)=f(n-1)+f(n-2)是非常正确的结论。

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

先列多项式:

  • f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-m)
  • f(n-1) = f(n-2) + f(n-3) + … + f(n-m) + f(n-m-1)

化简得:f(n) = 2f(n-1) - f(n-m-1)

 int Jump(int n,int m ) {
     // 当m小于n的时候就是上面的公式
     if(n > m){
         return 2*Jump(n-1, m)-Jump(n-1-m, m);
     }
     // 当m大于等于n的时候是和n级的相同了
     if (n <= 1) {
         return 1;
     } else {
         return 2 * Jump(n - 1,n);
     }
 }
  1. 用2 * 1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2 * 1的小矩形无重叠地覆盖一个2 * n的大矩形,总共有多少种方法

在这里插入图片描述

状态转移方程推导:

  • 若第一块矩形竖着放,后边还有n-1个2 * 1 小矩形去组成2 * (n-1)矩形,即此种情况下,有f(n-1)种覆盖方法。
  • 若两块横着放,后边还有n-2个2 * 1 小矩形去组成2*(n-2)矩形,此种情况下,有f(n-2)种覆盖方法。
  • 可得 f(n)=f(n-1)+f(n-2)
  1. 求最大连续子数组和{6,-3,-2,7,-15,1,2,2}

状态F(i):以第i个元素结尾的连续最大和

F(0):{6}
F(1):{6,-3},{-3}
F(2):{6,-3,-2},{-3,-2},{-2}
F(3):{6,-3,-2,7},{-3,-2,7},{-2,7},{7}
F(i) = Max(F(i - 1) + array[i], array[i])
  • F(i - 1):状态F(i)前的状态结果
  • array[i]:数组的第i个下标对应的数字

返回值:Max(F(i))


如有不同见解,欢迎留言讨论~~