// 问题背景: 10人围成圈,从1-3数数,数到3退出,求最后推出的人?
public static void main(String[] args){
// 约瑟夫环问题
// 法一:使用单向环连表
Linked head = initLinked();
Linked last = doGame(head);
System.out.println(last.val);
System.out.println("----------------");
// 法二:使用数组
int[][] arr = {{1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}};
System.out.println(doGame(arr));
}
private static int doGame(int[][] arr) {
int idx = 1;
for (;;) {
if (arr.length == 1) return arr[0][0];
int retCnt = arr.length;
for (int i = 0; i < arr.length; i ++) {
if (idx % 3 == 0) {
retCnt --;
arr[i][1] = 0;
System.out.println(idx + " | " + arr[i][0]);
}
idx ++;
}
int[][] newArr = new int[retCnt][];
int newIdx = 0;
for (int[] a : arr) {
if (a[1] != 0) {
newArr[newIdx ++] = a;
}
}
arr = newArr;
}
}
private static Linked doGame(Linked head) {
Linked prev = head;
int idx = 1;
for (;;) {
if (prev.next == prev) return prev;
if (idx % 3 == 0) {
System.out.println(idx + " | " + head.val);
Linked next = head.next;
prev.next = next;
head.next = null;
head = next;
} else {
prev = head;
head = head.next;
}
idx ++;
}
}
private static Linked initLinked() {
Linked head = new Linked(1), cur = head;
for (int i = 2; i < 11; i ++) {
Linked newCur = new Linked(i);
cur.next = newCur;
cur = newCur;
}
cur.next = head;
return head;
}
static class Linked {
int val;
Linked next;
public Linked(int val) {
this.val = val;
}
}