青蛙跳台阶问题(c实现)

青蛙跳台阶,1次跳1步,1次还可以跳2步。问n个台阶几种跳法

递归的思路:

无论是斐波那契还是汉诺塔等递归问题,都具有相同的,已经走过的过程,下一次迭代只是上次的结果和这次需要迭代的,就可以运用递归

思路:

一个问题直接求解时不好求解,如果可以将其划分成其子问题,并且子问题和原问题有相同的解法时,就可以使用递归的方式解决

递归的两个条件:

 1. 将问题划分成其子问题,要求:子问题要与原问题具有相同的解法

 2. 递归的出口

假设有一个函数f(n)可以算出n个台阶青蛙有几种跳法

当n=1   1种

当n=2    2种

当n>2

可以把这种情况看成,第一步跳一步后面有f(n-1)个(+)第一步跳2步后面有f(n-2)个方法,然而后面的方法数可以递归出来。

这种青蛙跳台阶的问题本质上就是一种斐波那契的变形

按照跳台阶的思路我一开始认为跳到最后一个台阶 前面还是N-1个台阶,F(N-1) = ?就是几

这种不对,还少了一种情况,还需要加上最后2个台阶一步跳上去 ,那么就是F(N-1) + F(N-2)

我觉得和从第一个台阶看也是这样的,第一个台阶剩下N-1个,第一第二个台阶一步跳上去还剩N-2个,也是F(N-1) + F(N -2)

那么如此就得出了如下的关系式

假设有3个台阶

青蛙第一次有两种跳法,要么跳一个,要么跳2个

跳一个还剩2个台阶,而跳2个台阶的方法数已知

跳2个还剩1个,而跳1个台阶的方法数已知

则运用递归,完整代码如下:

#include <stdio.h>

int f(int n)
{
	if ( n <= 0 )
	{
		printf("没台阶还算?\n");
		return 0;
	}else if(1 == n)
	{
		return  1;
	}
	else if (2 == n)
	{
		return  2;
	}
	else           //这种情况是n>2的情况,因为前面把情况都写了,最后就直接else。
		return f(n - 1) + f(n - 2);

}

int main()
{
	
	int n = 0;
	printf("请输入台阶数\n");
	scanf("%d", &n);
	int ret = 0;
	ret = f(n);
	printf("有%d种跳法\n", ret);
	return 0;
}

但是这种递归有很多冗余,计算了许多相同的f(n),和斐波那契数列的递归一样,递归在有时候是有缺陷的。可以用迭代的方式避免。例如斐波那契的时间复杂度为O(2^N)。

循环方式实现

力扣

class Solution {
public:
    int numWays(int n) 
    {
        if(n == 0)
        return 1;
        
        if(n<=2)
        {
            return n;
        }
        int f1 = 1;
        int f2 = 2;
        int ret = 0;
        for(int i = 3 ; i <= n; i++)
        {
            ret = (f1 + f2) % 1000000007;
            f1 = f2;
            f2 = ret;
        }
        return ret;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值