我的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();
}

四、代碼運行結果

在這裏插入圖片描述


  1. 一個很經典的算法題,分享給大家。根據上面的分析,可以看出來這是一個斐波那契數列問題,只要找出來規律,然後按照這個規律編碼實現就好了。
    在這裏插入圖片描述 ↩︎

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章