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);
    }

运行结果如下:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

启动Docker服务后显示Docker Engine stopped

1、重新启动Docker服务&#xff1a;打开Windows服务管理器&#xff08;可以在开始菜单中搜索&#xff09;&#xff0c;找到"Docker Desktop Service"或类似命名的服务&#xff0c;右键单击并选择"重启"。稍等片刻&#xff0c;看看是否重新启动成功 2、尝试…

如何快速落地LLM应用?通过Langchain接入千帆SDK

百度智能云千帆大模型平台再次史诗级升级&#xff01;在原有API基础上&#xff0c;百度智能云正式上线Python SDK&#xff08;下文均简称千帆 SDK&#xff09;版本并全面开源&#xff0c;企业和开发者可免费下载使用&#xff01;千帆SDK全面覆盖从数据集管理&#xff0c;模型训…

如何利用软文推广提升消费者“购买力”?

企业软文推广的目的大部分是为了将自己的产品卖出去&#xff0c;想要成功卖出去还得将重心放在消费者身上&#xff0c;今天媒介盒子就来分享&#xff0c;如何利用软文推广提升消费者的“购买力”。 一、 研究产品属性 产品是连接企业和消费者的桥梁&#xff0c;要想将产品卖出…

黄执中老师人际说服课思考总结(个人笔记整理 ②)

前言&#xff1a; 沟通和说服的区别&#xff1a;为什么沟通不能解决问题&#xff0c;处于劣势的一方&#xff08;承受问题的那方&#xff09;才想去沟通&#xff08;对方没有沟通动力&#xff09;。说服是温柔而有力的学科 - 劣势一方的武器。 说服是一门影响人的学问&#xff…

SQL Server 2022 安装步骤——SQL Server设置身份验证教程

目录 前言: 安装详细步骤: 第一步: 第二步: 第三步: 第四步: SQL Server 连接的方式: Window验证: SQL Server验证: 两者之间区别: 总结: SQL Server身份验证登录配置教程:​ 第一步: 第二步: 第三步: 番外篇: 前言: 本文讲解&#xff0c;如何安装SQL Server安…

自媒体项目详述

总体框架 本项目主要着手于获取最新最热新闻资讯&#xff0c;以微服务构架为技术基础搭建校内仅供学生教师使用的校园新媒体app。以文章为主线的核心业务主要分为如下子模块。自媒体模块实现用户创建功能、文章发布功能、素材管理功能。app端用户模块实现文章搜索、文章点赞、…

一分钟秒懂人工智能对齐 ( 文末送书 )

人工智能对齐 什么是人工智能对齐为什么要研究人工智能对齐人工智能对齐的常见方法延伸阅读写在末尾&#xff1a; 主页传送门&#xff1a;&#x1f4c0; 传送 什么是人工智能对齐 人工智能对齐&#xff08;AI Alignment&#xff09;指让人工智能的行为符合人的意图和价值观。 …

三季度净利润高达28.1亿元,2023的理想“高开高走”?

最近&#xff0c;理想汽车的好消息接二连三&#xff0c;先是月交付量突破四万辆大关。紧接着11月9日发布的2023年第三季度财报显示&#xff0c;理想汽车实现第三季度营收346.8亿人民币&#xff0c;同比增长271.2%。 今年以来&#xff0c;理想汽车的整体走势可谓“高开高走”。…

【JAVA学习笔记】65 - 文件类,IO流--节点流、处理流、对象流、转换流、打印流

项目代码 https://github.com/yinhai1114/Java_Learning_Code/tree/main/IDEA_Chapter19/src/com/yinhai 文件 一、文件&#xff0c;流 文件,对我们并不陌生&#xff0c;文件是保存数据的地方,比如大家经常使用的word文档,txt文件,excel文件..都是文件。它既可以保存一张图片…

归并排序 图解 递归 + 非递归 + 笔记

前置知识&#xff1a;讲解019-算法笔试中处理输入和输出&#xff0c;讲解020-递归和master公式 (1)左部分排好序&#xff0c;右部分排好序&#xff0c;利用merge过程让左右整体有序(2)merge过程:谁小拷贝谁&#xff0c;直到左右两部分所有的数字耗尽(3)递归实现和非递归实现(4…

NFT合约部署

部署合约&#xff1a; 1.web3 NFT合约部署工具 https://remix.ethereum.org/ 2.tron NFT合约部署工具 https://www.tronide.io/ 3.部署 web3 ERC721代码&#xff1a; // SPDX-License-Identifier: MIT pragma solidity ^0.8.2;import "openzeppelin/contracts/token/ERC7…

【java:牛客每日三十题总结-4】

java:牛客每日三十题总结 总结如下 总结如下 集合相关知识点 元素是否排序和插入顺序无关&#xff0c;取决与集合实现是否考虑了传入对象的java.lang.Comparable接口抽象类和接口相关知识 只能说越来越抽象了 java线程通信的方式 在Java中&#xff0c;常用的线程通信方式有两…

Leetcode_3:Pow(x,n)

题目描述&#xff1a; 实现 pow(x, n) &#xff0c;即计算 x 的整数 n 次幂函数。 示例 1&#xff1a; 输入&#xff1a;x 2.00000, n 10 输出&#xff1a;1024.00000示例 2&#xff1a; 输入&#xff1a;x 2.10000, n 3 输出&#xff1a;9.26100示例 3&#xff1a; 输入&…

Android 多点触控

三种类型 :接力型 /配合型 /单独型 单点触控 package com.example.myapplication.viewimport android.content.Context import android.graphics.Canvas import android.graphics.Paint import android.util.AttributeSet import android.view.MotionEvent import android.vi…

剑指offer(C++)-JZ21:调整数组顺序使奇数位于偶数前面(一)(算法-其他)

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 题目描述&#xff1a; 输入一个长度为 n 整数数组&#xff0c;实现一个函数来调整该数组中数字的顺序&#xff0c;使得所有的奇数…

d3.js

D3&#xff1a;Data-Driven Documents • 通过D3提供的接口来基于数据操控文档的各个图元。 标题对于D3(本讲解)最为重要的标签&#xff0c;主要操作的对象(画布) HTML - 导入D3.js D3.js作为JavaScript的外库&#xff0c;必须先将其导入&#xff0c;如&#xff1a; Python的…

Android 图层列表 、 LayerDrawable 、 layer-list \ 改变 seekbar thumb 滑块 的颜色

android 官网 &#xff1a; 图层列表 LayerDrawable / layer-list LayerDrawable 是管理其他可绘制对象数组的可绘制对象。列表中的每个可绘制对象均按照列表顺序绘制。列表中的最后一个可绘制对象绘于顶部。 每个可绘制对象均由单个 <layer-list> 元素内的 <item>…

计算机毕业设计:基于python机器学习的全国气象数据采集预测可视化系统 预测模型+爬虫(包含文档+源码+部署教程)

[毕业设计]2023-2024年最新最全计算机专业毕设选题推荐汇总 感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;希望帮助更多的人 。 1、摘 要 随着气候变化的不断加剧&#xff0c;气象数据的准确性…

方太集团合同档案管理平台,让数字化成果深度利用、可查可验

数字经济大背景下&#xff0c;方太集团积极拥抱企业数字化转型&#xff0c;推动合同档案业务管理数字化&#xff0c;助力业务档案高效融合&#xff0c;助力企业创新科技发展。 方太集团&#xff08;以下简称“方太”&#xff09;创建于1996年。作为一家以智能厨电为核心业务的…