Solution 18: 约瑟夫环问题
问题描述
n个数字(0,1,...,n-1)形成一个圆圈,从数字0开始。每次从这个圆圈中删除第m个数字,然后从被删除的下一个继续删除第m个元素,以此类推。
直到最后剩下一个数字,求出该数字。
解决思路
1. 使用循环链表模拟这一过程,计数器计数;
2. 递归思路
(图片来源:http://www.cnblogs.com/yangyh/archive/2011/10/30/2229517.html)
程序
public class JosephLoop { public int josephLoopByList(int n, int m) { if (n <= 0 || m <= 0) { return -1; } int cnt = n; boolean[] p = new boolean[n]; int k = 0; while (cnt > 1) { for (int i = 0; i < p.length; i++) { if (!p[i]) { ++k; if (k == m) { p[i] = true; --cnt; k = 0; } } } } for (int i = 0; i < p.length; i++) { // get the last one if (!p[i]) { return i + 1; } } return -1; } // recursion public int josephLoopRec(int n, int m) { if (n <= 0 || m <= 0) { return -1; } return helper(n, m, n) + 1; } private int helper(int n, int m, int i) { if (i == 1) { return (m - 1) % n; } return (helper(n - 1, m, i - 1) + m) % n; } }