先看下在10人成環,逢四去一的狀況下,對問題的分析:java
10我的手拉手圍成一圈,由第一個位置(index = 0)開始報數,數到 4 的人被 kick 出圈外,每次kick一我的,從新編號,又從 index = 0 的位置報數,以此向下類推:數組
新環是由(舊環中編號 - 最大報數值)% 舊總人數 獲得的,因此逆推時能夠由(新環中的數字 + 最大報數值)% 舊總人數 取得。即 old_number = ( new_number + count_number ) % old_sum。code
即在以 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; } } }