既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
n
n
n 的数组,用于在递归时存储
f
(
0
)
f(0)
f(0) 至
f
(
n
)
f(n)
f(n) 的数字值,重复遇到某数字时则直接从数组取用,避免了重复的递归计算。
所以我们设置一个数组,用于存放第一次计算某一个n
n
n的
jump(n)
。
当每一次要计算一个jump(n)
的时候,就先查看数组中以n
n
n 为下标的地方是否有值,有的话就可以不调用
jump(n)
,而直接从数组中取得结果值,否则再计算jump(n)
。
📝代码实现
#include <stdio.h>
long int f[1000]={0};
int jump(int n){
//当只有一阶台阶的时候,只有一种上台阶的方式。
//当有2阶台阶的时候,有2种上台阶的方式,一种是一次上一阶,还有一种是一次上2个台阶。
//现在设有n阶台阶,如果n>2,那种应该有(先跳一阶)+(先跳2阶)的方式
//如果先跳一阶,那么就有jump(n-1)中方式。如果先跳2阶,那么就有jump(n-2)中方式。
//因此可以知道共有jump(n-1) + jump(n-2)种方式。
if(n==1)
{
f[1]=1;
return f[1];
}
if(n==0)
{
f[0]=1;
return f[0];
}
if(n==2)
{
f[2]=2;
return f[2];
}
else
{
if(f[n-1]!=0)
{
if(f[n-2]!=0)
{
return (f[n-1]+f[n-2]);
}
else
{
f[n-2]=jump(n-2);
return (f[n-1]+f[n-2]);
}
}
else
{
if(f[n-2]!=0)
{
f[n-1]=jump(n-1);
return (f[n-1]+f[n-2]);
}
else
{
f[n-1]=jump(n-1);
f[n-2]=jump(n-2);
return (f[n-1]+f[n-2]);
}
}
}
}
int main()
{
int num = 0;
printf("请输入一个台阶数:> ");
scanf("%d", &num);
int ret = jump(num);
printf("小青蛙有 %d种 跳法\n", ret);
return 0;
}
运行结果👇
🍅 动态规划解法
很快我又发现,不必把所有的记录都记起来;
假设我有3阶楼梯,我只需要知道跳2阶和跳1阶的方法数是多少就可以算出跳3阶的方法数;
因此每次只需要保留 **n−
1
n-1
n−1阶** 和 **n
−
2
n-2
n−2阶** 的方法数。
📝代码实现
#include <stdio.h>
int jump(int n)
{
//n=0、1、2的时候,直接返回n即可
if (n < 3)
{
return n;
}
//第一个数为1
int one = 1;
//第二个数为2
int two = 2;
//用于存放前两个数之和
int sum = 0;
while (n > 2)
{
sum = one + two;
one = two;
two = sum;
n--;
}
return sum;
}
int main()
{
int num = 0;
printf("请输入一个台阶数:> ");
scanf("%d", &num);
int ret = jump(num);
printf("小青蛙有 %d种 跳法\n", ret);
return 0;
}
运行结果👇
2. 问题升级
🍑 题目描述
一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶……,也可以跳n级,求该青蛙跳上一个n级的台阶总共需要多少种跳法。
🍑 解题思路
一只青蛙要想跳到n级台阶,可以从一级,二级……,也就是说可以从任何一级跳到n级👇
当台阶为1级时,f
(
1
)
=
1
f(1)=1
f(1)=1;
当台阶为2级时,f
(
2
)
=
1
1
=
2
f(2)=1+1=2
f(2)=1+1=2;
当台阶为3级时,f
(
3
)
=
f
(
1
)
f
(
2
)
1
=
4
f(3)=f(1)+f(2)+1=4
f(3)=f(1)+f(2)+1=4;
当台阶为4级时,f
(
4
)
=
f
(
1
)
f
(
2
)
f
(
3
)
1
=
8
f(4)=f(1)+f(2)+f(3)+1=8
f(4)=f(1)+f(2)+f(3)+1=8;
当台阶为5级时,f
(
5
)
=
f
(
1
)
f
(
2
)
f
(
3
)
f
(
4
)
1
=
16
f(5)=f(1)+f(2)+f(3)+f(4)+1=16
f(5)=f(1)+f(2)+f(3)+f(4)+1=16;
所以递推公式我们很容易就能想到:f
(
n
)
=
f
(
n
−
1
)
f
(
n
−
2
)
…
…
f
(
2
)
f
(
1
)
f
(
0
)
f(n)=f(n-1)+f(n-2)+……+f(2)+f(1)+f(0)
f(n)=f(n−1)+f(n−2)+……+f(2)+f(1)+f(0)
最后这个f
(
0
)
f(0)
f(0)是可以去掉的,因为0级就相当于没跳,所以
f
(
0
)
=
0
f(0)=0
f(0)=0
然后我们把f
(
0
)
f(0)
f(0)去掉再转换一下:
f
(
n
−
1
)
=
f
(
n
−
2
)
f
(
n
−
3
)
…
…
f
(
2
)
f
(
1
)
f(n-1)=f(n-2)+f(n-3)+……+f(2)+f(1)
f(n−1)=f(n−2)+f(n−3)+……+f(2)+f(1);
推导过程👇
我们列两个等式:
①f
(
n
)
=
f
(
n
−
1
)
f
(
n
−
2
)
f
(
n
−
3
)
…
f
(
2
)
f
(
1
)
f(n) = f(n-1) + f(n-2) +f(n-3) + … + f(2) + f(1)
f(n)=f(n−1)+f(n−2)+f(n−3)+…+f(2)+f(1)
②f
(
n
−
1
)
=
f
(
n
−
2
)
f
(
n
−
3
)
…
f
(
2
)
f
(
1
)
f(n-1) = f(n-2) +f(n-3) + … + f(2) + f(1)
f(n−1)=f(n−2)+f(n−3)+…+f(2)+f(1)
由①-②得,f
(
n
)
=
2
f
(
n
−
1
)
f(n) = 2f(n-1)
f(n)=2f(n−1)
🍑 代码实现
🍅 递归方法
📝代码示例
int jump(int n)
{
if (n == 1)
{
return 1;
}
else
{
return 2 \* jump(n - 1);
}
}
int main()
{
int num = 0;
printf("请输入一个台阶数:> ");
scanf("%d", &num);
int ret = jump(num);
printf("小青蛙有 %d种 跳法\n", ret);
return 0;
}
运行结果👇
🍅 非递归方法
当然这里也可以用非递归的方式来实现
那么非递归怎么去思考呢?
可以这样理解:f
(
1
)
=
1
=
2
0
f(1) = 1 = 2^0
f(1)=1=20
f
(
2
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
int jump(int n)
{
if (n == 1)
{
return 1;
}
else
{
return 2 \* jump(n - 1);
}
}
int main()
{
int num = 0;
printf("请输入一个台阶数:> ");
scanf("%d", &num);
int ret = jump(num);
printf("小青蛙有 %d种 跳法\n", ret);
return 0;
}
运行结果👇
🍅 非递归方法
当然这里也可以用非递归的方式来实现
那么非递归怎么去思考呢?
可以这样理解:f
(
1
)
=
1
=
2
0
f(1) = 1 = 2^0
f(1)=1=20
f
(
2
[外链图片转存中…(img-BhtASvms-1715741765506)]
[外链图片转存中…(img-Sb8q3jex-1715741765507)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!