「这是我参与2022首次更文挑战的第26天,活动详情查看:2022首次更文挑战」
1.1 递归基础
- 递归概述:以编程的角度来看,递归指的是 方法定义中调用方法本身 的现象
- 递归解决问题的思路:
- 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求
- 解递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
- 递归解决问题要找到两个内容:
- 递归出口:否则会出现内存溢出
- 递归规则:与原问题相似的规模较小的问题
public class Demo {
public static void main(String[] args) {
//回顾不死神兔:每个月兔子个数:1、1、2、3、5、8...;求第20月的兔子个数
int arr[] = new int[20];
arr[0] = 1;
arr[1] = 1;
for(int i=2;i< arr.length;i++) {
arr[i] = arr[i-1] + arr[i-2];
}
System.out.println(arr[19]); //6765
// f(20); //1,java.lang.StackOverflowError:当堆栈溢出发生时抛出一个应用程序递归抬深
System.out.println(f(20)); //6765
}
//递归解决问题首先定义个方法
public static int f(int n) {
//1,return f(n-1)+f(n-2);
//2,给出递归出口防止内存溢出
if(n==1 || n==2) {
return 1;
}else {
return f(n-1)+f(n-2);
}
}
}
1.2 递归与迭代
- 1.迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。即迭代过程的每一次结果,都是由对前一次所得结果施行相同的运算步骤得到的。
- 2.理论上递归和迭代可以相互转换。迭代一定可以转化为递归,递归不一定能转化为迭代。
- 3.实际应用中递归的算法要比迭代效率低,因为程序每调用一个函数,都要为其分配栈空间。但理论上,对于同一问题,递归和迭代的算法时间复杂度是相同的。
- 4.对于某些问题,递归是最精炼和适当的算法,但对于其他的问题,递归则不如迭代解法直观。
1.3 案例:汉罗塔问题
汉诺塔问题描述:
- 有3根柱子A、B、C,A柱上有n个盘子,盘子的大小不等,大的盘子在下,小的盘子在上。
- 要求将A柱上的n个盘子移到C柱上,每次只能移动一个盘子。
- 在移动过程中,可以借助于任何一根柱子(A、B、C),但必须保证3根柱子上的盘子都是大的盘子在下,小的盘子在上。
思路:
- 可以理解成只有两种情况,当其中只有一个盘子,直接从A移动到C
- 当有两个的时候将第一个移动到B,最下面的移动到C,再将第一个移动到C
- 所以当有n个的时候,将上面的 n-1 当做一个整体移动到B,将 n 移动到C,再将上面的 n-1 移动到C
实现类
public class Hanoi {
public static void main(String[] args) {
hanoi(3,'A','B','C');
}
//n:n个盘子,x:开始的柱子,y:中间的柱子,z:目标柱子
public static void hanoi(int n,char x,char y,char z) {
if(n==1) {
System.out.println("第1个盘子从"+x+"移动到"+z);
//无论有多少个盘子都认为只有两个。上面所有盘子为n-1,下面为n
}else {
//将前面n-1个盘子移到中间位置
hanoi(n-1,x,z,y);
//移动下面的盘子到目标位置
System.out.println("第"+n+"个盘子从"+x+"移动到"+z);
//把上面n-1个盘子从中间位置移动到目标位置
hanoi(n-1,y,x,z);
}
}
}
结果输出:
第1个盘子从A移动到C
第2个盘子从A移动到B
第1个盘子从C移动到B
第3个盘子从A移动到C
第1个盘子从B移动到A
第2个盘子从B移动到C
第1个盘子从A移动到C`