一 .问题概述
青蛙跳台阶问题,也称为青蛙过河或者上楼问题,是一个经典的递归和动态规划问题。
问:一只青蛙站在楼梯的最底层,它需要跳到最高层。每次跳跃,青蛙可以跳上1个或2个台阶。问青蛙跳上第n阶台阶总共有多少种不同的跳法。
这个问题的解题思路与裴波那契数列问题相似,可以用递归和动态规划方法解决。下面将分别介绍这两种方法。
二 .解题方法
1 .经典递归
运用递归时,咱们首先先把问题分析清楚。跳台阶时,无疑就两种方式,一次跳一个或者一次跳两个。由下图可知,当台阶数 n <= 2 时,跳跃方式就等于台阶数;如果台阶数 n >=2时,到达第n阶台阶的方法数是到达第n-1阶和第n-2阶台阶方法数的和。
递归公式可以表示为: f(n)=f(n−1)+f(n−2),而递归终止条件就是 :当 n递减到 <= 2
那么,分析完之后,咱们就可以动手写代码了,咱们用C来实现。
#include <stdio.h>
int climbStairs(int n)
{
if (n <= 2)
{
return n;
}
return climbStairs(n - 1) + climbStairs(n - 2);
}
int main()
{
int n = 0;
printf("请输入台阶的数量: ");
scanf("%d", &n);
printf("跳跃%d个台阶的方式有%d种\n", n, climbStairs(n));
return 0;
}
2 . 动态规划
动态规划是一种更高效的方法,它通过填充一个数组来避免重复计算。设dp[i]
表示到达第i阶台阶的方法数,状态转移方程与递归方法相同: dp[i]=dp[i−1]+dp[i−2]
初始化:
dp[0] = 1
,因为在第0阶台阶上无需跳跃。dp[1] = 1
,因为只有一种方法跳到第1阶台阶。
边界条件:当i > 1
时,使用状态转移方程 dp[i]=dp[i−1]+dp[i−2]。
以下是使用C语言实现的动态规划函数:
#include <stdio.h>
int climbStairs(int n)
{
if (n <= 1)
{
return 1;
}
int dp[n + 1];
dp[0] = dp[1] = 1;
for (int i = 2; i <= n; i++)
{
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
int main()
{
int n;
printf("请输入台阶的数量: ");
scanf("%d", &n);
printf("跳跃%d个台阶的方式有%d种\n", n, climbStairs(n));
return 0;
}
三.总结
1. 递归方法:时间复杂度为O(2^n),因为每个问题被分解为两个子问题,导致问题规模迅速翻倍。空间复杂度为O(n),用于递归调用的栈空间。
2. 动态规划方法:时间复杂度为O(n),空间复杂度也为O(n),用于存储dp
数组。
所以对于青蛙跳台阶问题,动态规划提供了一个更高效且易于理解的解决方案。通过避免重复计算,动态规划显著提高了算法的效率。
但值得注意的是,上述动态规划方法中,数组dp[n+1]表达式中使用了非常量,在有些编译环境可能会报错,解决方法就是把它重新定义成一个空间较大的数组来实现函数功能。
最后祝小伙伴们早日成为技术大牛~
共勉@