当前位置: 首页 > news >正文

递归-极其优雅的问题解决方法(Java)

递归的定义

大名鼎鼎的递归,相信你即使没接触过也或多或少听过,例如汉诺塔问题就是运用了递归的思想,对于一些学过c语言的同学来说,它可能就是噩梦,因为我当时就是这么认为的(不接受反驳doge)

递归到底是什么捏,递归是一种解决问题的思想它将复杂的问题转换为无数嵌套的小规模同逻辑问题,可以简化代码,使问题易于理解,要理解递归一定要先理解递归函数

递归函数

一个直接或间接调用自己的函数,就是递归函数

递归函数一定包括递归条件和基线条件,递归条件就是调用自己的条件,基线条件则是结束递归的条件

⭐太抽象了,直接通过代码理解把 

递归实现阶乘

public class recurrence {public static void main(String[] args) {//递归函数调用 factorial(4);//执行步骤://递归中的  递// 1.  求factorial(4)// return 4 * factorial(3)           由于factorial(3)未知,故该问题需先求解factorial(3)// 2.  求factorial(3)// return 3 * factorial(2)           同上由于factorial(2)未知,问题又转换为求factorial(2)// 3.  求factorial(2)// return 2 * factorial(1)           同上由于factorial(1)未知,问题又转换为求factorial(1)// 4.  求factorial(1)       // factorial(1)满足n = 1(满足基线条件,递归的 递 结束,开始进行 归 ) ,故factorial(1) = 1// 5.  由于factorial(1)=1得解,故factorial(2)继续执行,return 2,即factorial(2)=2// 6.  factorial(2)=2,故factorial(3)=6可解// 7.  factorial(3)=6,故factorial(4)=24可解// 8.  递归的 归 结束,函数结束}public static int factorial(int n){//基线条件if(n==1){return 1;}else{                  //递归条件return n*factorial(n-1); }}
}

细品应该不难理解,知识输入完毕,开始输出知识,下面进入递归的应用吧

数组的正反遍历

public static void ergodic(int[] arr ,int index){//正向遍历     由递遍历System.out.println(arr[index]);//递归                                                                                          if(index < arr.length-1 && 0 <= index) {       //递归条件ergodic(arr , index+1);}//反向遍历      由归遍历System.out.println(arr[index]);}

 使用

ergodic(new int[]{1,2,3,4,5},0);

结果

二分查找

不熟悉二分查找的可以看详解二分查找(Java)

public static int binarySearch(int[] arr, int target ,int l ,int r){if(l > r){return -1;}int mid=(l + r)>>>1;             //右移运算效果为 /2if(arr[mid]<target){return binarySearch(arr,target,mid+1,r);}else if(target < arr[mid]){return binarySearch(arr,target,l,mid-1);}else{return mid;}
}

冒泡排序(优化版)

public static void bubbloSort(int[] arr , int arrSize){int greatLeft=arrSize-1;for (int i = 0; i < arrSize-1; i++) {if(arr[i] > arr[i+1]){int temp;temp=arr[i];arr[i]=arr[i+1];arr[i+1]=temp;greatLeft=i;        //最后置换的位置可视为未排序的尾结点,因为后面没有置换说明后面是有序的不需要再冒泡了}}if(greatLeft!=arrSize-1){bubbloSort(arr , arrSize);}
}

插入排序

public static void insertSort(int[] arr ,int low){if(low==arr.length){return ;}for (int i = low; 0 < i; i--) {if(arr[i-1]>arr[i]){int temp=arr[i];arr[i]=arr[i-1];arr[i-1]=temp;}else {break;}}insertSort(arr,low+1);
}

多路递归

实现斐波那契数列

    //斐波那契数列public static int fibonacci(int n){if(n == 0){return 0;}else if(n == 1){return 1;}return fibonacci(n-1)+fibonacci(n-2);}

优化斐波那契

//(优化记忆)斐波那契数列public static int fibonacci(int n ){int[] arr =new int[n+1];Arrays.fill(arr,-1);arr[0]=0;arr[1]=1;return f(n ,arr);}private static int f(int n , int[] arr){if(arr[n]!=-1){return arr[n];}int value=f(n-1,arr)+f(n-2,arr);arr[n]=value;return value;}

尾递归 

尾递归就是最后语句是函数调用语句的递归函数,尾递归可以使部分编程语言(Scala , C++)编译器对爆栈递归的进行优化,可由递归调用变为平级调用提前释放栈内存

Java不可实现,故应避免较深的递归调用而使用循环替代

 

分析递归的时间复杂度

主定理

其中 a为子问题数       1/b为问题规模是原来的多少倍        f(n)为其他项时间复杂度

http://www.lryc.cn/news/254556.html

相关文章:

  • VSCode搭建STM32开发环境
  • 解决CentOS下PHP system命令unoconv转PDF提示“Unable to connect or start own listener“
  • 软件测试外包干了2个月,技术进步2年。。。
  • Linux-网络服务和端口
  • Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)读书笔记 目录
  • 阿里云Arthas使用——通过watch命令查看类的返回值 捞数据出来
  • Redis中持久化策略RDB与AOF优缺点对比
  • 通用plantuml 时序图(Sequence Diagram)模板头
  • Domino多Web站点托管
  • 防火墙补充NAT
  • 配置和管理VLAN
  • dtaidistance笔记:dtw_ndim (高维时间序列之间的DTW)
  • 2 文本分类入门:TextCNN
  • 算法初阶双指针+C语言期末考试之编程题加强训练
  • 【Spark基础】-- 宽窄依赖
  • Spatial Data Analysis(六):空间优化问题
  • PHP短信接口防刷防轰炸多重解决方案三(可正式使用)
  • C#大型LIS检验信息系统项目源码
  • 【C语言】数据在内存中的存储
  • Java聊天程序(一对一)简单版
  • Linux下超轻量级Rust开发环境搭建:一、安装Rust
  • 定义一个学生类,其中有3个私有数据成员学号、姓名、成绩,以及若于成员。 函数实现对学生数据的赋值和输出。
  • 1.2 C语言简介
  • 小白学Java之数组问题——第三关黄金挑战
  • 各大期刊网址
  • 使用autodl服务器,在A40显卡上运行, Yi-34B-Chat-int4模型,并使用vllm优化加速,显存占用42G,速度18 words/s
  • unity 2d 入门 飞翔小鸟 下坠功能且碰到地面要停止 刚体 胶囊碰撞器 (四)
  • 速达软件任意文件上传漏洞复现
  • Name or service not knownstname
  • [Geek Challenge 2023] web题解