/**
* 题目:孩子们的游戏(圆圈中最后剩下的数) 然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列,直到剩下最后一人。
* 思考: 1)F(N,M)=(F(N-1,M)+M)%N 2)链表 3)数组
*
* @author hexiaoli
*/
class Node {
Node next = null;
int val;
public Node(int val) {
this.val = val;
}
}
public class Main {
public static int LastRemaining_Solution1(int n, int m) {
if (n == 0 || m == 0) {
return -1;
}
int s = 0;
for (int i = 2; i <= n; i++) {
s = (s + m) % i;
}
return s;
}
public static int LastRemaining_Solution2(int n, int m) {
if (n <= 0 && m <= 0)
return -1; // 边界
Node head = new Node(0); // 头结点, 值为0
Node pre = head;
Node temp = null;
for (int i = 1; i < n; i++) {
temp = new Node(i);
pre.next = temp;
pre = temp;
}
temp.next = head;// 构成循环链表
int count = 0;
while (count != n) {
pre = head;
for (int i = 1; i < m - 1; i++) {
pre = pre.next;// 找到第m个节点前驱,也就是第m-1个节点
}
pre.next = pre.next.next;// 删除第m个节点
head = pre.next;// 更新头结点
count++;
}
return head.val;
}
public static int LastRemaining_Solution3(int n, int m) {
if (n < 1 || m < 1)
return -1;
int[] array = new int[n];
int i = -1, step = 0, count = n;
while (count > 0) { // 跳出循环时将最后一个元素也设置为了-1
i++; // 指向上一个被删除对象的下一个元素。
if (i >= n)
i = 0; // 模拟环。
if (array[i] == -1)
continue; // 跳过被删除的对象。
step++; // 记录已走过的。
if (step == m) { // 找到待删除的对象。
array[i] = -1;
step = 0;
count--;
}
}
return i;// 返回跳出循环时的i,即最后一个被设置为-1的元素
}
public static void main(String[] args) {
System.out.println(LastRemaining_Solution1(10, 3));
System.out.println(LastRemaining_Solution2(10, 3));
System.out.println(LastRemaining_Solution3(10, 3));
}
}