Java 算法篇-深入理解递归(递归实现:青蛙爬楼梯)

🔥博客主页: 小扳_-CSDN博客
❤感谢大家点赞👍收藏⭐评论✍
 

 

文章目录

        1.0 递归的说明

        2.0 用递归来实现相关问题

        2.1 递归 - 阶乘

        2.2 递归 - 反向打印字符串

        2.3 递归 - 二分查找

        2.4 递归 - 冒泡排序

        2.5 递归 - 冒泡排序2.0

        2.6 递归 - 插入排序

        2.7 递归 - 斐波那契

        2.8 递归 - 兔子问题

        2.9 递归 - 青蛙爬楼梯


        1.0 递归的说明

        递归就是在一个函数中调用自身。这样做可以让我们解决一些问题,比如计算斐波那契数列、阶乘等。

        递归函数一般包括两部分:基本情况和递归情况。基本情况是指当问题变得很小,可以直接得到答案时,递归就可以停止了。递归情况是指在解决问题的过程中,需要不断地调用自身来解决更小规模的问题。

        对于递归这个算法,简单的来说,方法自身调用自身的时候,需要有终止的条件,在运行过程中不断的趋向终止条件。还有递归总的来说有两个动作:第一个动作是递出,方法不断的在栈区中创建出来,直到达到了条件就会停止。第二个动作,达到条件停止了,就会回归,指方法在栈区中依次执行完后就销毁。

        2.0 用递归来实现相关问题

        以下的问题都较为简单,采取直接用代码来演示。

        2.1 递归 - 阶乘

代码如下:

    //阶乘public static void main(String[] args) {System.out.println(fun(5));}public static int fun(int n) {if (n == 1) {return 1;}return n * fun(n-1);}
}

运行结果为:

        2.2 递归 - 反向打印字符串

代码如下:

    //反向打印字符串public static void main(String[] args) {String str = "lisi";fun2(str,0);}public static void fun2 (String s, int n) {if (n == s.length()) {return;}fun2(s,n + 1);System.out.println(s.charAt(n));}

运行结果:

        2.3 递归 - 二分查找

代码如下:

    //二分查找public static void main(String[] args) {int[] arr = {1,3,5,7,9,10,13};System.out.println(fun3(arr, 0, arr.length - 1, 4));}public static int fun3 (int[] arr, int left, int right, int target) {int mid = (left + right) >>> 1;if (left > right) {return -1;}if(arr[mid] < target) {return fun3(arr, mid + 1,right,target);} else if (target < arr[mid]) {return fun3(arr,left,right - 1,target);}else {return mid;}}

  运行结果如下:

        没有找到就返回 - 1

        2.4 递归 - 冒泡排序

代码如下:

    //冒泡排序public static void main(String[] args) {int[] arr = {1,5,2,4,9,1,3};fun4(arr, arr.length - 1);System.out.println(Arrays.toString(arr));}public static void fun4 (int[] arr, int n) {if (n == 0) {return;}for (int i = 0; i < n; i++) {if (arr[i] > arr[i + 1]) {int temp = arr[i];arr[i] = arr[i+1];arr[i+1] = temp;}}fun4(arr,n-1);}

运行结果如下:

        2.5 递归 - 冒泡排序2.0

        对冒泡排序进行升级,假如 int[] arr = {2,1,1,3,4,5,9},这种只需要遍历一遍即可,但是对与已经用递归实现的冒泡不止遍历一次。因此,需要得到升级版冒泡排序。

        思路为:对于后续的元素已经是排好序了,就不用再遍历了。每一次交换完元素之后记下来 i 索引,i 之后的元素已经是排好序的,i 之前的元素还需要继续遍历,看是否还需要交换。

代码如下:

    //冒泡排序升级版public static void main(String[] args) {int[] arr = {1,3,2,4,9,10,13};fun4(arr, arr.length - 1);System.out.println(Arrays.toString(arr));}public static void fun4 (int[] arr, int n) {if (n == 0) {return;}int j = 0;for (int i = 0; i < n; i++) {if (arr[i] > arr[i + 1]) {int temp = arr[i];arr[i] = arr[i+1];arr[i+1] = temp;j = i;}}fun4(arr,j);}

        如果还不是很清晰的话,可以一步步来调试一下,来对比两种冒泡的执行过程。

        2.6 递归 - 插入排序

        思路:假设第一个元素已经排序好了的,在已经排好的元素的后一个元素记录为 low,这个 low 索引对应的元素需要用临时变量来接受,只要找到比这个索引对应的元素小的值,就可以插入到比它小的值的后一个索引位置了,当然,每一次对比之后,都需要往后移一个位置,以便直接插入。当 low 一直每一个加 1 ,当 low 等于数组的长度时,就该停止了继续递归下去了。

代码如下:

public class Recursion {// 插入排序public static void main(String[] args) {int[] arr = {1,3,2,4,9,10,13};fun5(arr,1);System.out.println(Arrays.toString(arr));}public static void fun5 (int[] arr,int low) {if (low == arr.length) {return;}int temp = arr[low];int i = low - 1;while (arr[i] > temp) {arr[i + 1] = arr[i];i--;}arr[i + 1] = temp;fun5(arr,low + 1);}

运行结果如下:

        2.7 递归 - 斐波那契

代码如下:

    //斐波那契public static void main(String[] args) {System.out.print(fun6(1) +" ");System.out.print(fun6(2) +" ");System.out.print(fun6(3) +" ");System.out.print(fun6(4) +" ");System.out.print(fun6(5) +" ");System.out.print(fun6(6) +" ");}public static int fun6 (int n) {if (n == 0) {return 0;}if (n == 1 || n == 2) {return 1;}return fun6(n-1) + fun6(n - 2);}

运行结果如下:

        2.8 递归 - 兔子问题

        一个斐波那契的变体问题。

        思路:观察第六个月的兔子个数,是否等于第四个月的兔子的总数加上第五个月的兔子总数;类推,第五个月的兔子个数,是否等于第四个月的兔子的总数加上第三个月的兔子总数;以此类推,是符合斐波那契逻辑的。

代码如下:

    //兔子问题public static void main(String[] args) {System.out.print(fun7(1) + " ");System.out.print(fun7(2) + " ");System.out.print(fun7(3) + " ");System.out.print(fun7(4) + " ");System.out.print(fun7(5) + " ");}public static int fun7 (int n) {if (n == 1) {return 1;}if (n == 0) {return 0;}return fun7(n -1) + fun7(n - 2);}

运行结果如下:

        2.9 递归 - 青蛙爬楼梯

        一个斐波那契的变体问题。

题目如下:

列举一下:

        实现思路: 一个阶梯一种跳法,两个阶梯两种跳法。重点,如果有四个阶梯,从后往前分析,分两种情况;第一种,从第二个台阶直接一下子跳两阶上来。第二种,从第三个台阶跳一阶上来。那么从考虑第一种情况,前面两阶是不是就是只有两种方法。考虑第二种情况,前面的三个台阶是不是就是前面已经算出来的方式跳法个数了。因此,这就是一个斐波那契的变体问题。

代码如下:

    //青蛙问题public static void main(String[] args) {System.out.print(fun8(1) + " ");System.out.print(fun8(2) + " ");System.out.print(fun8(3) + " ");System.out.print(fun8(4) + " ");System.out.print(fun8(5) + " ");System.out.print(fun8(6) + " ");}public static int fun8 (int n) {if (n == 1) {return 1;}if (n == 2) {return 2;}return fun8(n-1) +fun8(n-2);}

运行结果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/212061.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【腾讯云 HAI域探秘】StableDiffusionWebUI一小时搞定100张设计图

目录 前言一、选择 HAI部署的优势二、HAI 搭建AI绘图服务实现思路三、生成设计图操作流程1、新建HAI应用2、StableDiffusionWebUI&#xff08;1&#xff09;功能介绍&#xff08;2&#xff09;页面转中文&#xff08;3&#xff09;线稿生成图 四、部署StableDiffusionWebUI服务…

【附代码】判断线段是否相交算法(Python,C++)

【附代码】判断线段是否相交算法&#xff08;Python&#xff0c;C&#xff09; 文章目录 【附代码】判断线段是否相交算法&#xff08;Python&#xff0c;C&#xff09;相关文献测试电脑配置基础向量旋转向量缩放向量投影推导 点乘定义推导几何意义 叉乘定义推导几何意义 判断线…

怎样用AIDL Service 传递复杂数据

大家都知道在Android中通过AIDL可以跨进程调用Service中的数据&#xff0c;网上也有很多实例&#xff0c;但是大部分实例都是关于基本数据类型的远程调用&#xff0c;很少讲到复杂数据的调用&#xff0c;今天我用一个例子来演示一下怎样用AIDL Service 传递复杂数据。 我们分2…

【神印王座】龙皓晨美妆胜过月夜,魔神皇识破无视,撮合月夜阿宝

Hello,小伙伴们&#xff0c;我是拾荒君。 《神印王座》国漫第82集已更新&#xff0c;拾荒君和大多数人一样&#xff0c;更新就去看了。魔神皇枫秀&#xff0c;威严凛然&#xff0c;突然空降月魔宫&#xff0c;整个宫殿都在这股无与伦比的强大气息中颤栗。为了顺利躲避魔神皇的…

延时任务定时发布,基于 Redis 与 DB 实现

目录 1、什么是延时任务&#xff0c;分别可以使用哪些技术实现&#xff1f; 1.2 使用 Redis 和 DB 相结合的思路图以及分析 2、实现添加任务、删除任务、拉取任务 3、实现未来数据的定时更新 4、将数据库中的任务数据&#xff0c;同步到 Redis 中 1、什么是延时任务&#xff…

【工具栏】热部署不生效

目录 配置热部署&#xff1a; 解决热部署不生效&#xff1a; 首先检查&#xff1a; 第一步&#xff1a; 第二步&#xff1a; 第三步&#xff1a; 第四步&#xff1a; 配置热部署&#xff1a; https://blog.csdn.net/m0_67930426/article/details/133690559 解决热部署不…

深入理解JVM 类加载机制

深入理解JVM 类加载机制 虚拟机如何加载Class文件&#xff1f; Class文件中的信息进入到虚拟机后会发生什么变化&#xff1f; 类加载机制就是Java虚拟机把描述类的数据从Class文件加载到内存&#xff0c;并对数据进行校验、转换解析和初始化&#xff0c;最终形成可以被虚拟机…

6.2.SDP协议

那今天呢&#xff1f;我们来介绍一下sdp协议&#xff0c;那实际上呢&#xff1f;sdp协议非常的简单。我们如果拿到一个stp的文档去看的话&#xff0c;那你要分阅里边的所有的内容会觉得很枯燥&#xff0c;但实际上呢&#xff0c;如果我们按照这张图所展示的结构去看stp的话。你…

[MySQL] MySQL 表的增删查改

本篇文章对mysql表的增删查改进行了详细的举例说明解释。对表的增删查改简称CRUD : Create(创建), Retrieve(读取)&#xff0c;Update(更新)&#xff0c;Delete&#xff08;删除&#xff09;。其中重点是对查询select语句进行了详细解释&#xff0c;并且通过多个实际例子来帮助…

【从零开始实现意图识别】中文对话意图识别详解

前言 意图识别&#xff08;Intent Recognition&#xff09;是自然语言处理&#xff08;NLP&#xff09;中的一个重要任务&#xff0c;它旨在确定用户输入的语句中所表达的意图或目的。简单来说&#xff0c;意图识别就是对用户的话语进行语义理解&#xff0c;以便更好地回答用户…

【RtpRtcp】1: webrtc m79:audio的ChannelReceive 创建并使用

m79中,RtpRtcp::Create 的调用很少 不知道谁负责创建ChannelReceiveclass ChannelReceive : public ChannelReceiveInterface,public MediaTransportAudioSinkInterface {接收编码后的音频帧:接收rtcp包: