LastRemaining45(圓圈中最後剩下的數字(約瑟夫問題))
阿新 • • 發佈:2019-02-18
import java.util.LinkedList;
/**
* @author LemonLin
* @Description :LastRemaining45
* @date 2018/9/4-20:45
*
* 題目:圓圈中最後剩下的數字(約瑟夫問題)
*
* 題目:0, 1, … , n-1 這 n 個數字排成一個圈圈,
* 從數字 0 開始每次從圓圏裡刪除第 m 個數字,下一次,從m+1開始數,數第
* m個刪除,以此類推。求出這個圈圈裡剩下的最後一個數字。
*
* 問題,需要解決如何迴圈移除的問題?用%(list.size())
*
*需要解決如何進行下一步繼續迴圈的問題,比如第一遍數到0-M,如何第二遍從m+1開始數第m個數:
*
* index=-1;
* while(size>1){
* index=(index+m)%size();
* index--;
* }
* 原因,第一次取m-1,
* 第二次是index--是因為size也減小了一個一;
* 迴圈是用%size();
*
*
* 解題思路:
* 解法一:利用環形連結串列處理問題,這裡用LinkedList的效能比ArrayList的效能好,
* 因為我們不斷的要刪除List中的某個元素。如果用ArrayList裡面有大量的System.arraycopy。
*
*
* 解法二:開O(n)的輔助空間,建造一個boolean陣列,大小為總共數字的個數和,預設boolean
* 陣列的每個元素都是false,數到誰的時候,將陣列對對應index的值改為true。
* 知道最後只剩下一個元素值為false,得到此index。
*/
public class LastRemaining45 {
/**
*
* @param n 表示圓圈最大的數
* @param m 表示從第幾個數開始刪除
* @return 剩下的最後一個數
*/
public int LastRemaining_Solution(int n, int m) {
/**
* 異常輸入的判斷
*/
if (n==0||m==0){
return -1;
}
LinkedList<Integer> linkedList = new LinkedList<>();
for (int i=0;i<n;i++){
linkedList.add(i);
}
/*
for(Iterator iter = linkedList.iterator(); iter.hasNext();) {
System.out.println("原始linkedList==="+iter.next());;
}*/
int index =-1;
while (linkedList.size()>1 ){
index=(index+m)%(linkedList.size());
linkedList.remove(index);
/*System.out.println("移除過程中的linkedList==="+m);*/
index--;
}
/* for(Iterator iter = linkedList.iterator(); iter.hasNext();) {
System.out.println("移除之後linkedList==="+iter.next());
}*/
return linkedList.get(0);
}
public static void main(String[] args) {
LastRemaining45 lastRemaining45 = new LastRemaining45();
int test = lastRemaining45.LastRemaining_Solution(5, 3);
System.out.println(test);
}
}