//看了帖子後以爲有趣就實現了一把遞歸的約瑟夫算法算法
package test; /** * 500個小孩圍成一圈,從第一個開始報數:1,2,3,1,2,3,1,2,3,……每次報3的小孩退出 問最後剩下的那個小孩,在之前500人裏是第幾個??? */ public class Test { /** * 約瑟夫標準循環非遞歸解法 * @param n * @param m * @return */ public static int f2(int n, int m){ int index = 0; for (int i = 2; i <= n; i++) { index = (index + m) % i; } return index +1; } /** * 約瑟夫遞歸算法 * @param n * @param m * @return 返回的結果+1 = 最終結果 */ public static int f(int n,int m){ int t = 0; if(n==1){ return t; }else{ t = ( f(n-1, m) + m)%n; } return t; } public static void main(String[] args) { // int n = 500; int m = 3; //約瑟夫標準循環非遞歸解法 System.out.println(f2(n, m));//此方法來自帖子 /* (函數)index表示(變量)n我的玩遊戲報(常量)m退出最後勝利者的編號.則有遞推公式: index(1) = 0; index(n) = (index(n-1) + m)%n; (n>1) 這個公式不是隻考慮一種場景得出的結果,而是抽象出廣泛的n得出的結論, */ /* *f(1) = 0;//第0個 *f(2) = 1;//第1個 *f(3) = 1;//第2個 * */ //參考上面的提示寫了下約瑟夫的遞歸算法 System.out.println(f(n, m)+1); } }
今天看到一個LinkedList版本的,測試了,結果同樣,補充上:函數
public static int removeNM(int n, int m) { LinkedList ll = new LinkedList(); for (int i = 0; i < n; i++) ll.add(new Integer(i + 1)); int removed = -1; while (ll.size() > 1) { removed = (removed + m) % ll.size(); System.out.println("出列:"+(ll.get(removed))); ll.remove(removed--); } return ((Integer) ll.get(0)).intValue(); }
打印結果:測試
436code
436遞歸