1. 程式人生 > 其它 >演算法筆記 -- 約瑟夫環問題Java兩種寫法

演算法筆記 -- 約瑟夫環問題Java兩種寫法

// 問題背景: 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; } }