我的Java学习之路(十)-- 经典算法兔子繁殖问题

经典算法兔子繁殖问题

  • 一、问题描述
  • 二、问题分析
  • 三、代码实现
  • 四、代码运行结果

一、问题描述

  • 一对兔子,从第3个月开始,每个月生1对小兔崽子,且每只兔子都不会死亡;
  • 小兔崽子也会按照上面的过程进行生小兔崽子
  • 问第N月后,有几对兔子

二、问题分析

月份 兔子数量(对) 说明
1月 1 第1月,①兔子不能生
2月 1 第2月,①兔子不能生
3月 2 第3月,①兔子满3月,生1对兔子②
4月 3 第4月,①兔子生1对兔子③,②兔子不能生
5月 5 第5月,①兔子生1对兔子④,②③兔子不能生
6月 8 第6月,①兔子生1对兔子⑤,②兔子生1对兔子⑥,③兔子不能生

从上面的分析来看,从第三个月开始,每个月的兔子数量都是前两个月的和 1
可推导出公式:sum(n) = sum(n - 1) + sum(n - 2), n > 2

三、代码实现

  1. 递归算法
/**
 * 计算兔子数量 (递归算法)
 * 
 * @param month 月份
 * @return
 * @throws Exception
 */
private static int rabbit(int month) throws Exception {
     
	if (month <= 0) {
     
		// 不大于0的月份没有意义
		throw new Exception("月份必须大于0");
	}

	if (month <= 2) {
     
		// 第1、2个月,兔子只有1对
		return 1;
	}
	
	// 第3个月开始,兔子有前1月 + 前2月的兔子数量
	return rabbit(month - 1) + rabbit(month - 2);
}
  1. 循环算法
/**
 * 计算兔子数量 (循环算法)
 * 
 * @param month 月份
 * @return
 * @throws Exception
 */
private static int rabbit2(int month) throws Exception {
     
	int[] nums = new int[month];
	if (month <= 0) {
     
		// 不大于0的月份没有意义
		throw new Exception("月份必须大于0");
	}

	for (int i = 0; i < month; i++) {
     
		if (i < 2) {
     
			// 第1、2个月,兔子只有1对
			nums[i] = 1;
		} else {
     
			// 第3个月开始,兔子有前1月 + 前2月的兔子数量
			nums[i] = nums[i - 1] + nums[i - 2];
		}
	}
	
	// 返回最后一个月份的兔子数量
	return nums[month - 1];
}
  1. 在main方法中调用
public static void main(String[] args) {
     
	Scanner key = new Scanner(System.in);
	System.out.println("请输入一个整数表示月份:");
	int month = key.nextInt();
	try {
     
		System.out.println("递归算法:" + month + "月后,共有" + rabbit(month) + "对兔子");
		System.out.println("循环算法:" + month + "月后,共有" + rabbit2(month) + "对兔子");
	} catch (Exception e) {
     
		e.printStackTrace();
	}
	key.close();
}

四、代码运行结果

我的Java学习之路(十)-- 经典算法兔子繁殖问题_第1张图片


  1. 一个很经典的算法题,分享给大家。根据上面的分析,可以看出来这是一个斐波那契数列问题,只要找出来规律,然后按照这个规律编码实现就好了。
    我的Java学习之路(十)-- 经典算法兔子繁殖问题_第2张图片 ↩︎

你可能感兴趣的:(Java,java,算法,leetcode)