公司組織考試,一拿到考題,就是算法裏說的約瑟夫環,仔細想一想 之前老師將的都忘了,仍是本身琢磨把~java
package basic.gzy; import java.util.Iterator; import java.util.LinkedList; import java.util.Queue; /** * 約瑟夫環 報數遊戲 好比 5,3 則最後一個退出遊戲的是4號 * 五我的圍城環,數到三退出遊戲,而後往下輪,最後一個爲倖存者 * 要知足報數小於人數 * @author mac * */ public class BSYX { public static void main(String[] args) { // System.out.println("---生存者"+baoshu1(5,3)); // System.out.println("---生存者"+baoshu1(12,3)); System.out.println("---生存者"+baoshu2(5,3)); } public static int baoshu1(int num, int count) { // 最後退出的是第n我的 int n = 0; // 剩餘的人 int rest = num; // 利用數組初始化爲0做爲標識位 int[] arr = new int[num + 1]; // 初始化次數 int index = 1; for (int i = 1, j = 1; i < num + 1; i++, j++) { //跳過已退出的數據 while (arr[i] == 1) { if(i<num) { i++; }else { i=1; } } if (rest == 1) { n = i; break; } if (j == 1) { System.out.println(); System.out.print("第" + index + "次遊戲," + i + "[" + j + "],"); } else if (j < count ) { System.out.print(i + "[" + j + "],"); } else { System.out.print(i + "[" + j + "]--" + i + "退出遊戲"); // 重置j會++故設爲0,遊戲次數+1,數組作標記位已退出,剩餘人少1 j = 0; index++; rest--; arr[i] = 1; } if (i == num ) { // 回到頭,會++故設爲0 i = 0; } } return n; } /** * 利用隊列 * @param num * @param count * @return */ public static int baoshu2(int num, int count) { int n = 0; int rest = num; int index = 1; int l = 0; Queue<Integer> list = new LinkedList<Integer>(); for(int i=1;i<num+1;i++) { list.add(i); } while(!list.isEmpty()) { Integer poll = list.poll(); l++; if(rest == 1) { n=poll; break; } // 靈活運用求餘 if(l%count == 1) { System.out.println(); list.add(poll); System.out.print("第" + index + "次遊戲," + poll + "[" + 1 + "],"); }else if(l%count==0) { System.out.println(poll + "[" + count + "]--" + poll + "退出遊戲"); rest --; index++; }else { list.add(poll); System.out.print(poll + "[" + poll%count + "],"); } } return n; } }
總結:第一種是本身想的lowlow的寫法,代碼冗餘,可讀性通常。第二種利用了隊列雙向鏈表LinkedList也是一個環的特性,頗爲巧妙。還有一種就是以面向對象的思想,目前還在完善算法