算法学习|入门级递归算法题目(基于Java)

递归小贴士

何谓递归?
	一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常
把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递
归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了
程序的代码量。

方法:
1)找重复
	①找到一种划分方法
	②找到递推公式或等价转换
	(均是父问题转换为子问题)
2)找变化的量
3)找出出口

题目1:打印n的阶乘

分析:

n的阶乘为:n(n-1)(n-2)···1
设函数 f(n) 表示求n的阶乘,则 f(n-1) 为 (n-1) 的阶乘
因此 f(n) 可以表示为 n*f(n-1)
求n的阶乘 等价于 求n*{(n-1)的阶乘}
如下图就像切蛋糕,自己处理一小块,剩余留给函数自己做,逐步重复
方法:
1)找重复:①求阶乘操作在重复 ②递推公式:f(n)=n*f(n-1)
2)找变化量:f(n) - - - n逐渐变小,求f(n)调用f(n-1),求f(n-1)调用f(n-2),如此往复
3)找出口:直到n减小到1,1的阶乘为1,则返回1
题目1解析

代码:

public class Test{
	public static void main(String[] args) {
		//测试题目1:打印n的阶乘
		int n = 5;
		System.out.println("题目1:"+n+"的阶乘为"+f(n));
	}
	
	//题目1:打印n的阶乘
	static int f(int n) {
		//设置出口
		if(n == 1) {
			return 1;
		}
		//第一部分自己做,剩下的交给函数自己处理
		return n * f(n - 1);
	}
}

题目2:打印i~j

分析:

例如:打印3 ~ 15
输出结果:3 4 5 6 7 8 ···15
设函数 f(i,j) 表示打印 i ~ j: i (i+1) (i+2) ··· j
则函数 f(i+1,j) 表示打印 (i+1) ~ j:(i+1) (i+2) ··· j
因此f(i,j) 可表示为: i f(i+1,j)
同上一题思路一致:欲打印i~j,自己手动打印i,剩下的(i+1) ~ j 由函数自己完成
方法:
1)找重复:①打印的操作在重复 ②递推公式:f(i,j) = i f(i+1,j)
2)找变化量:f(i,j) - - - i逐渐变大,求 f(i,j) 调用 f(i+1,j),求 f(i+1,j) 调用f(i+2,j),如此往复
3)找出口:直到 i==j 时刚好打印完最后一个数,所以 i>j 时跳出方法,return返回
题目2

代码:

public class Test {
	public static void main(String[] args) {
		// 测试题目2:打印i到j
		int i = 3;
		int j = 15;
		//调用函数
		f(i, j);
	}

	// 题目2:打印i-j
	static void f(int i, int j) {
		//设置出口
		if (i > j) {
			return;
		}
		//打印第一个数,剩下的交给函数自己处理
		System.out.print(i + " ");
		f(i + 1, j);
	}
}

题目3:对数组arr的所有元素求和

分析:

与上两题思路一致,自己手动求第一部分的和,后面的所有由函数自己处理
例如:数组arr = {1, 2 ,3 ,4 ,5}
输出结果:15
设函数f(arr,0)实现功能:从第0位开始到最后一位对数组arr求和
则f(arr,1)实现从第1位开始到最后一位对数组求和
所以可以将f(arr,0)表示为: arr[0] + f(arr,1)
方法:
1)找重复:①求和的操作在重复 ②递推公式:f(arr,0)=arr[0] + f(arr,1)
2)找变化量:f(arr,begin) - - - begin逐渐变大,求 f(arr,0) 调用 f(arr,1),求 f(arr,1) 调用f(arr,2),如此往复
3)找出口:直到 begin==arr.length - 1时刚好求和完最后一个数,所以 begin>arr.length -1 时跳出方法,return 0返回

代码:

public class Test {
	public static void main(String[] args) {
		//测试题目3:对数组arr所有元素求和
		int[] arr = { 1, 2, 3, 4, 5 };
		int getSum = f(arr, 0);
		System.out.println(getSum);
	}

	// 题目三:对数组arr所有元素求和
	static int f(int[] arr, int begin) {
		//设置出口
		if (begin > arr.length - 1) {
			return 0;
		}
		//重复,调用自身
		return (arr[begin] += f(arr, begin + 1));
	}
}

题目4:字符串反转

分析:

例如:将字符串“abcdef”反转
输出结果:fedcba
思路:每次反着取字符串最后一个元素,依次存入一个新字符串中
设函数f(src,end)实现功能将src原字符串反转,则函数f(src,end-1)实现将src的前end-1位反转
则函数f(src,end)可以表示为 src.charAt(end) + f(src,end-1)
方法:
1)找重复:①字符反转的操作在重复 ②递推公式:
ff(src,end)=src.charAt(end) + f(src,end-1)
2)找变化量:f(src,end) - - - end逐渐变小,求 f(src,end) 调用 f(src,end-1),求 f(src,end-1) 调用f(src,end-2),如此往复
3)找出口:直到 end == 0 时刚好将取到字符串第一位,所以 end < 0 时跳出方法,return""返回

代码:

public class Test {
	public static void main(String[] args) {
		//测试题目4:字符串反转
		String s = "abcdef";
		System.out.println(f(s, s.length() - 1));
	}

	// 题目四:字符串反转
	static String f(String src, int end) {
		//设置出口
		if (end < 0) {
			return "";
		}
		//调用自身实现递归
		return src.charAt(end) + f(src, end - 1);
	}
}

题目5:求斐波那契数列的第n位

分析:

斐波那契数列:1 1 2 3 5 8 13 21…
规律:从第3位开始,第n位数值等于前两位数值的和
设函数 f(n) 实现求得第n位斐波那契数列的数值
f(n) 可以表示为:f(n-1) + f(n-2)
方法:
1)找重复:①求斐波那契数列的操作在重复 ②递推公式:f(n) =f(n-1) + f(n-2)
2)找变化量:f(n) - - - n逐渐变小,求 f(n) 调用 f(n-1)和f(n-2),求 f(n-1) 调用f(n-2)和f(n-3),如此往复
3)找出口:直到 n == 1 或 2时斐波那契数列值为1,则函数返回1,return 1

代码:

public class Test {
	public static void main(String[] args) {
		// 测试题目5:斐波那契数列
		int N = 7; // 1 1 2 3 5 8 13
		System.out.println(f(N));
	}

	// 题目五:求斐波那契数列的第N位
	static int f(int N) {
		//设置出口
		if (N == 1 || N == 2) {
			return 1;
		}
		//调用自身函数
		return f(N - 1) + f(N - 2);
	}
}

骚话时刻:
所有循环都能用递归改造,初学可以试试将一些简单循环改成递归实现
递归这玩意儿,可以用下面这幅图直观展示
(图片来自Baidu,侵删)
图片来自百度
这不由得让我想到了耳熟能详的和尚的故事:
从前有座山,山里有座庙,庙里有个和尚,和尚和小和尚讲故事,故事讲的是:
从前有座山,山里有座庙,庙里有个和尚,和尚和小和尚讲故事,故事讲的是:
从前有座山,山里有座庙,庙里有个和尚,和尚和小和尚讲故事,故事讲的是:
······
咳咳,但一定要记住了,递归算法一定要有出口,不然就成了死循环!
还有还有,讲故事呢一定要有结尾,不然会被胖揍一顿
表情包来自百度图片

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值