//看了帖子后觉得有趣就实现了一把递归的约瑟夫算法
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(); }
打印结果:
436
436