1、第一種實現:算法
實現比較簡單,直接貼現成的代碼了,第一種實現:數組
/** * 總人數 * * @param d */ private static void sortQuerry1(int d) { // TODO 先構造一個數組 ArrayList<Integer> arr = new ArrayList<>(); for (int i = 1; i <= d; i++) { arr.add(i); } int xiabiao = -1; int count = 0; // 循環查找 int mun = 10; while (arr.size() > 1) { xiabiao++; count++; if (count == 3) { System.out.println("移除的是" + arr.get(xiabiao)); arr.remove(xiabiao); count = 0; xiabiao = xiabiao - 1; } if (xiabiao == (arr.size() - 1)) { xiabiao = -1; } if (arr.size() == 1) { System.out.println("最後一個剩餘的人是:" + arr.get(0)); break; } } }
2、優化和改進測試
思考1分鐘,上述這種實現的缺點是什麼?優化
時間到了,答案就在Arraylist上面,Arraylist.remove()方法的實現原理是將數組第i個元素以後的全部元素,向前挪一位,這樣會致使時間複雜度增長。spa
如何改進呢?儘可能避免ArrayList.remove()方法的使用。下面是一種實現:code
private static void sortQuerry2(int d) { // TODO 先構造一個數組 ArrayList<Boolean> arr = new ArrayList<>(); for (int i = 1; i <= d; i++) { arr.add(true); } int xiabiao = -1; int count = 0; int x=0; // 循環查找 while (true) { xiabiao++; if(xiabiao>=arr.size()-1) xiabiao=xiabiao%arr.size(); if(arr.get(xiabiao)==false) continue; if (x>=arr.size()-1) { System.out.println("最後一個剩餘的人是:" + (xiabiao+1)); break; } count++; if (count == 3) { System.out.println("移除的是" + (xiabiao+1)); arr.set(xiabiao, false); count = 0; x++; System.out.println("X是" + x); } if (xiabiao == (arr.size() - 1)) { xiabiao = -1; } } }
3、測試對比:blog
兩組數據分別是200000,400000rem
public static void main(String[] args) { System.out.println("請輸入一個數字:");//200000,400000 Scanner scanner = new Scanner(System.in); int d = scanner.nextInt(); long startTime=System.currentTimeMillis(); sortQuerry1(d); long endTime=System.currentTimeMillis(); System.out.println("消耗時間:"+(endTime-startTime)/1000.000); }
第一組測試數據200000:get
sortQuerry1耗時: 3.919 sortQuerry2耗時:3.304class
第二組測試數據400000:
sortQuerry1耗時: 13.443 sortQuerry2耗時:7.157
當數據量大的時候,算法二明顯要快於算法1。
以上歡迎交流。