递归和一些有趣的算法题

递归指的是在方法内部对方法自身调用;递归一般用于一些常见的算法的解决,在实际应用中,
比如对文件夹内部文件的递归检索;以及树形菜单的显示;递归是对循环的一种补充 。
递归,就是在运行的过程中调用自己。
构成递归需具备的条件:
1. 子问题须与原始问题为同样的事,且更为简单;
2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。
经典的递归问题:

一、约瑟夫环

	有100个人围成一个圈(编号0-99),从第0号的人开始从1报数,凡报到3的倍数的人离开圈子,然后再数下去,
	直到最后只剩一个人为止,问此人原来的位置是多少号?
	public static void main(String[] args) {
		//声明布尔类型数组,用于标记这个人是否在圈中
		boolean[] b = new boolean[100];
		//初始化所有人都位于圈中(设置true)
		for(int i = 0;i < b.length;i++){
			b[i] = true;
		}
		
		//初始化圈中的总人数
		int len = b.length;
		//声明计数器,统计是否到达3
		int count = 0;
		//初始化索引,记录当前数到圈中的位置
		int index = 0;
		
		//开始循环报数
		while(len > 1){
			//判断当前位置的人是否在圈中
			if(b[index]){
				//计数器递增
				count++;
				//判断是否到达3
				if(count == 3){
					//人数减少
					len--;
					//标记此人离开圈子
					b[index]=false;
					//计数器归零
					count = 0;
				}
			}
			//数组索引递增
			index++;
			if(index == b.length){
				index = 0;
			}
		}
		
        //循环判断,数组中为true的元素的位置(即为剩下的人原来的位置)
		for(int i = 0;i<b.length;i++){
			if(b[i]){
				System.out.println(i);
				break;
			}
		}
	}

李白打酒

话说大诗人李白,一生好饮。幸好他从不开车。
一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:
无事街上走,提壶去打酒。
逢店加一倍,遇花喝一斗。
这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。 
请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。
像这样的答案一共有多少呢?请你计算出所有可能方案的个数(包含题目给出的)。
public class LiBaiDaJiu {
	//记录方法一共有多少个
	 static int count = 0;
	// b为酒馆数量,f为花的数量,a为酒的量
	public static int func(int b, int f, int a) {
        //处理小酒馆数量、花的数量、酒的余量异常情况
		if (b < 0 || f < 0 || a < 0) {
			return 0;
		}
		// 最后一个遇见花并且把酒喝光
		if (b == 0 && f == 1 && a == 1) {
			count++;
			return 1; 
		}
		
		// 逢店加一倍                  遇花喝1斗             
		return func(b - 1, f, 2 * a) + func(b, f - 1, a - 1);
	}
	
	public static void main(String[] args) {
		//初始时店为5个,花为10个,酒为2斗
		func(5,10,2);
		System.out.println(count);
	}
}

39级台阶

小明看完电影《第39级台阶》,离开电影院的时候,他数了数视觉的台阶数,恰好是39级。站在台阶前,
他突然又想起一个问题: 如果我每一步只能迈上1个或2个台阶,先迈左脚,然后左右交替,
最后一步迈右脚,也就是说一共要迈偶数步。那么上完39级台阶,有多少种不同的上法呢?
public class TaiJie {
	static int count = 0;//上台阶的方法数量

	//t为已经上的台阶数目   foot为上台阶时的步数
	static void method(int t,int foot){
		//处理步数异常的情况
		if(t > 40){
			return;
		}
		//台阶数为39,步数为偶数时上台阶的方法加一种
		if(t == 39 && foot % 2 == 0){
			count++;
			return;
		}
		//一次上一个台阶
		method(t+1,foot+1);
		//一次上两个台阶
		method(t+2,foot+1);
	}
	public static void main(String[] args) {
		//初始状态是一个台阶也没有上,一步也没有走
		method(0,0);
		//输出上台阶方法的个数
		System.out.println(count);
	}
}

递归可以让复杂的问题变的简单,我们只需要给递归一个出口,它就可以帮我们把所有的可能性都计算出来,递归极大程度的减少了代码量,所以在理解的时候变得有点困难,但我们自己可以不用知道递归的内部具体是如何实现的,只需要知道该如何去用,递归是我们解决算法问题的好帮手!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值