利用遞歸思想解決約瑟夫環問題(Java 描述)

先看下在10人成環,逢四去一的狀況下,對問題的分析:java

10我的手拉手圍成一圈,由第一個位置(index = 0)開始報數,數到 4 的人被 kick 出圈外,每次kick一我的,從新編號,又從 index = 0 的位置報數,以此向下類推:數組

新環是由(舊環中編號 - 最大報數值)% 舊總人數  獲得的,因此逆推時能夠由(新環中的數字 + 最大報數值)% 舊總人數  取得。即 old_number = ( new_number + count_number ) % old_sumcode

即在以 k 爲出環報數值的約瑟夫環中, m 人環中的第 n 次出環編號能夠由(m - 1)人環中的第(n - 1)次出環編號經過特定運算推出。blog

再看下圖:遞歸

因此,代碼以下所示:it

public class Test {
	public static void main(String[] args) {
		//初始化數組
		int[] arr = new int[500];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = i;
		}
		
		//利用遞歸思想推導的位置轉換公式求解最後剩下的人的位置
		int pos = 0;
		int countNum = 3;
		for (int i = 1; i <= arr.length; i++) {
			pos = (pos + countNum) % i;
		}
		System.out.println(arr[pos]);
		
		//遞歸方法的驗證
		int position = Test.f(arr.length, 3);
		System.out.println(arr[position]);
	}
	
	//利用遞推求解最後剩下的人的位置
	public static int f(int sumNum, int countNum) {
		if (sumNum == 1) {
			return 0;
		} else {
			return (f(sumNum - 1, countNum) + countNum) % sumNum;
		}
	}
}
相關文章
相關標籤/搜索