Java中方法的概念以及递归的讨论

image-20210731091051295

2、实参形参的关系

实参:在方法中,实际传递的数值就是实际参数。比如上面的main函数中, int c = add(a, b); 这里的a和b就是实际参数,称为实参。

形参:在被调用的方法里,由实参传递过来的数值,就称为形式参数。形参是实参的一份临时拷贝。也就是说,main函数传递的a和b,与add方法中的a和b,虽然都是10和20(上面代码中),但是二者并不是来自同一块内存空间:如下图所示:

image-20210731092639924

二、方法的重载


1、重载所能解决的问题

在我们平常写代码中,少不了数据的加减乘除。也少不了对不同类型的数据进行四则运算。假设:我们就写了上面的代码(add方法),我们用浮点数(小数)调用add方法,会有什么情况发生?

image-20210731093511684

此时大家就会想,我重新写一个double类型的方法不就行了吗。

没错,就是再次写一个double类型的add就行啦。在C语言中,我们写的函数(方法),不能够写重命的。比如,我写两个add的函数。函数名就是叫add。一模一样,在C语言中是不允许的。

但是在java中,这是可以。也就是这节所讲的 方法重载。

image-20210731094140670

根据形参的类型和形参的个数,去寻找被调用的方法。

上面的代码,分别调用了add方法,虽然都叫add。但是形参类型不一样。所以是两个不同的方法。这就叫重载。

重载的规则

  • 方法名相同

  • 方法的参数不同。(形参类型不同,个数不同)

  • 方法的返回值类型不影响重载

:当方法的方法名相同,参数相同,但返回值类型不同的时候,这不构成重载。

三、递归的概念


1、递归的概念

一个方法在自己调用自己时,就称为“递归”。

当一个大问题,是由若干个小问题,并且这些小问题的解决方法,都是一样的。这样的问题,很大可能就能用递归去解决。

递归相当于数学上的**“数学归纳法**”,有一个起始条件, 然后有一个递推公式

例如,我们求N!

起始条件: N= 1的时候, N!为1. 这个起始条件相当于递归的结束条件.

递归公式:求N!,直接不好求,可以把问题转换成N!=> N * (N-1)!

例如代码:

public class Main {

public static void main(String[] args) {

int n = 5; //求5的阶乘

System.out.println(fact(n));

}

public static int fact (int n) {

if (n == 1) { //递归结束的条件

return 1;

}

return n * fact(n - 1); //例如5! = 5 * 4! -》 5 * 4 * 3! ,一直递归到1的阶乘,就结束

}

}

2、递归的练习

1)、汉诺塔问题

汉诺塔游戏(7K7K小游戏链接)。在开始讲解之前,大家还是先去玩一玩汉诺塔游戏,看看是什么规则。更容易的理解下面的代码。

牛客网OJ题链接

汉诺塔游戏规则:

​ 现有三根柱子,我们分别叫 left, mid,right。现在有3个圆盘left柱子上,3个圆盘的大小关系为:从上往下,圆盘越来越大。

​ 每次只能取出一个圆盘,并且圆盘在取和放的时候,必须在这三根柱子上完成。不能取出来放到其他地方。

​ 且,大的圆盘不能放到小的圆盘上。

​ 问,怎么移动圆盘,让圆盘从left柱子,移动到right柱子上。

情况一:我们先从1个圆盘举例说明, 我们直接从left柱,移动到right柱即可

image-20210731101434879

情况二: 2个圆盘的情况

image-20210731103006968

image-20210731103451510

情况三: 3个圆盘的情况

image-20210731110229686

image-20210731110729536

image-20210731111313377

这就是大致的思路:

  1. 先将N - 1层移动到mid柱子,给最下面那一层让路。

  2. N - 1层移开之后,路就让出来了。此时移动第N层圆盘即可。

  3. 此时第一步移动的 N- 1层圆盘 还在mid柱子上,现在就是从 mid柱子 移动到 right柱子上。

不要去深究每一步的细节,抓好大致的思路,确定好递归终止的条件。宏观的去想这个问题,就能够很好地抓到问题的本质。

public class Main {

public static void main(String[] args) {

//汉诺塔

int n = 3;

hanoiTower(n, “left”, “right”, “mid”);

}

public static void hanoiTower(int n, String from, String to, String mid) {

if (n == 1) {

System.out.println("move 1 from " + from + " to " + to);

return; //记得返回,终止递归

}

hanoiTower(n - 1, from, mid, to); //图1 -> 图2

System.out.println("move " + n + " from " + from + " to " + to); //图2 -> 图3

hanoiTower(n - 1, mid, to, from); //图3 -> 图4

}

}

image-20210731112628355

2)、青蛙跳台阶

青蛙跳台阶 OJ题链接

image-20210731112824534

情况一:一步台阶 只能跳一次,就跳完了; 1种

image-20210731113831749

情况二:两步台阶 题意是,青蛙一次可以跳一步台阶,也可以跳两步台阶。所以情况二的跳法是 2 种

image-20210731114449556

情况三:三步台阶

image-20210731114852381

现在摆在我面前的问题就是。我要么跳一步台阶。我要么跳两步台阶。

img

不对,是摆在青蛙面前的问题!!!口误口误!

假设1:青蛙跳一步台阶后,还剩两个台阶没跳。此时是不是又回到了两层台阶的决策问题(上文情况二);

假设2:青蛙跳两步台阶后,还剩一个台阶没跳。此时是不是又回到了一层台阶的决策问题(上文情况一);

我们把这两种情况的假设,结果加起来,就是三层台阶的所有跳法了!!!

再往下,四层、五层……,推导的思路,不就展开了嘛

image-20210731120736250

public class Main {

public static void main(String[] args) {

int n = 3; //台阶数

System.out.println(jumpFloor(n));

}

public int jumpFloor(int target) {

if (target == 1) { //情况一

return 1;

}

if (target == 2) { //情况二

return 2;

}

return jumpFloor(target - 1) + jumpFloor(target - 2); //情况三

}

}

3)、青蛙跳台阶(进阶)(递归->动态规划)

青蛙跳台阶(进阶)OJ链接

image-20210731121515751

看完题目,各位有什么感想???

是不是跟初级的,区别不是很大?递归终止的条件还是一步台阶和两步台阶的情况。

情况一和情况二的情况,我们就不说了,跟上文初阶的一模一样。还是1种跳法和2种跳法;我们重点来看一下三层台阶的情况。

情况三: 三层台阶

三层台阶:也就是说青蛙一次可以跳到3层台阶。弹跳力见涨啊!(注意:并不是说,青蛙就一次只能跳3层台阶,题意是(1 ……n层中 ,每一层 它都可以一次跳过)。

假设青蛙一次最大跳三层:

​ 假设一:青蛙第一次跳一层台阶,还剩两个台阶没跳 -> 两层台阶的决策问题

​ 假设二:青蛙第一次跳两层台阶 ,还剩一个台阶没跳 -> 一层台阶的决策问题。

​ 假设三:青蛙第一次跳三层台阶,没有台阶跳了 -> 0层台阶的决策问题。

image-20210731150643466

那如果是 四层台阶 五层台阶 N层台阶 呢? 那是不是有几层,就有几种假设情况?那就需要相加!!!来看这个题的代码:

public class Main {

public static void main(String[] args) {

int n = 3; //假设就是3层台阶

System.out.println(frogJumpPlus(n));

}

public static int frogJumpPlus(int n) {

if (n == 1) {

return 1;

}

if (n == 2) {

return 2;

}

int res = 1; //当前,需要选择一种的跳法

//此处的for循环,就是去尝试,跳1步、2步、3步……一直跳到n层台阶,将这些情况全部加起来,就是当前的结果

for (int i = 1; i < n; i++) {

res += frogJumpPlus(n - i); //i控制台阶数,每次循环,都减一步台阶。去递归所有的台阶

}

return res;

}

}

上面的代码,就是经典的递归方式,去解这个题。

其实,在台阶数足够大时,这样的递归,会有很多的重复计算:比如:

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-kxuDNIkT-1715719555793)]

[外链图片转存中…(img-L3eyc7pk-1715719555794)]

[外链图片转存中…(img-fKXmslHz-1715719555794)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 26
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值