递归思想
将原问题分解为小问题,小问题的解决方式与大问题的解决方式一样,解决小问题就解决了大问题
递归的概念
一个方法在执行的过程中调用自身就称为“递归”;
递归就相当于数学的“数学归纳法”有一个起始条件(终止条件),有一个递推公式;
递归的必要条件
- 将原问题划分成其子问题(子问题必须与原问题解法相同)
- 递归有出口
递归实现求n!
//递:3*fac(2)-->2*fac(1)-->1 归:1-->fac(1)*2-->fac(2)*3-->找到结果
public static int fac(int n){
if (n == 1) {
return 1;
}
int tmp=n*fac(n-1);//fac调用函数自身
return tmp;
}
public static void main(String[] args) {
System.out.println(fac(3));
}
按顺序打印一个数字的每一位(例如1234打印1 2 3 4)
//n=1234 func(1234/10)(此时不<=9)-->func(123/10)-->func(12/10)-->得到func(1)-->小于9return 12%10=2-->123%10=3-->1234%10=4
//注意:若没有return那么就没有结束条件-->会一直在栈上开辟内存-->导致栈溢出
public static void func(int n){
if(n<=9){
System.out.println(n);
return;
}
func(n/10);
System.out.println(n%10);
}
public static void main(String[] args) {
func(1234);
}
计算1+2+3+4+...+n
public static int sum(int n){
if (n==1){
return 1;
}else {
return n+sum(n-1);
}
}
public static void main(String[] args) {
System.out.println(sum(10));//假设n=10
}
//此题递归实现相比循环实现
//递归:代码较少、但不易理解浪费空间较多(每次都在在栈上开辟空间)
//循环:代码较多、容易理解浪费空间较少
实现输出斐波那契数列的第n项
//求斐波那契数列的第n项 递归实现(会出现大量的重复计算)
public static int fib(int n){
if(n==1||n==2){
return 1;
}
return fib(n-1)+fib(n-2);
}
public static void main(String[] args) {
System.out.println(fib(5));
}
//求斐波那契数列第n项 循环实现 //效率明显高于递归实现
public static int fib1(int n){
int f1=1;
int f2=1;
int f3=0;
for (int i = 3; i <= n; i++) {
f3=f1+f2;
f2=f1;
f1=f3;
}
return f3;
}
public static void main(String[] args) {
System.out.println(fib1(5));
}
递归实现输入一个非负整数组成他的数字之和 例如:2023应该返回2+0+2+3 应输出7
public static int func1(int n){
if (n<=9){
return n;
}
return n%10+ func1(n/10);
}
public static void main(String[] args) {
System.out.println(func1(2023));
}
递归实现汉诺塔
//假设有三个柱子p1,p2,p3
// 有n个盘子在p1 先将n-1个盘子从p1借助p3移动到p2 再将p2的n-1个盘子借助p1移动到p3
public static void han(int n,char p1,char p2,char p3){
if (n == 1) {
move(p1, p3);
return;
}
han(n-1,p1,p3,p2);
move(p1,p3);
han(n-1,p2,p1,p3);
}
public static void move(char p1,char p2){
System.out.println(p1+"->"+p2);
}
public static void main(String[] args) {
han(1,'a','b','c');
han(3,'A','B','C');
}