遞迴題目練習 約瑟夫問題

2021-10-04 18:23:36 字數 1979 閱讀 9627

參考鏈結

題目描述

約瑟夫問題是乙個非常著名的趣題,即由n個人坐成一圈,按順時針由1開始給他們編號。然後由第乙個人開始報數,數到m的人出局。現在需要求的是最後乙個出局的人的編號。

給定兩個int n和m,代表遊戲的人數。請返回最後乙個出局的人的編號。保證n和m小於等於1000。

測試樣例:

5 3返回:4

主要思路

**如下

//遞迴實現

class joseph

return lastincycle(n, m) + 1;

}int lastincycle(int n, int m)

return (lastincycle(n - 1, m) + m) % n;

}};//迭代逆推實現

public int getresult(int n, int m)

int last = 0;

if(n == 1)

for(int i = 2; i <= n; i++)

return last+1;//注意編號是1-n編號的,而演算法是從0~n-1排序的

}

題目描述

約瑟夫問題是乙個著名的趣題。這裡我們稍稍修改一下規則。有n個人站成一列。並從頭到尾給他們編號,第乙個人編號為1。然後從頭開始報數,第一輪依次報1,2,1,2…然後報到2的人出局。接著第二輪再從上一輪最後乙個報數的人開始依次報1,2,3,1,2,3…報到2,3的人出局。以此類推直到剩下以後乙個人。現在需要求的即是這個人的編號。

給定乙個int n,代表遊戲的人數。請返回最後乙個人的編號

測試樣例:

5返回:5

主要思路一(數學推導實現)

**如下

//遞迴實現

class joseph

int result = lastincycle(n, 2);

return result + 1;

}int lastincycle(int n, int m)

int temp = n % m == 0 ? n / m : n / m + 1;

return (lastincycle(temp, m + 1) + temp - 1) % temp * m;

}};

主要思路二(鍊錶實現)

鍊錶實現:參考鏈結

解題思路例子:

由於涉及到頻繁的刪除操作,故資料結構應該選擇鍊錶,這裡選擇linkedlist,其底層實現是迴圈雙鏈表。

每一輪報數完畢之後,將鍊錶尾部節點移動到鍊錶首部,開始新一輪的報數。

鍊錶中僅剩乙個節點,程式結束。

舉個例子:假設n = 24,第乙個人編號為1。

(1)第一輪:依次報1,2,1,2…然後報到2的人出局,則第一輪過後未出局的編號為1、3、5、7、9、11、13、15、17、19、21、23;

(2)第二輪:從上一輪最後乙個報數的人開始依次報1,2,3,1,2,3…報到2,3的人出局。我這裡做的處理是,先將上一輪最後乙個報數的編號移動到最前面,即23、1、3、5、7、9、11、13、15、17、19、21;然後開始第二輪報數,未出局的編號為23、5、11、17;

(3)第三輪:從上一輪最後乙個報數的人開始依次報1,2,3,4,1,2,3,4…報到2,3,4的人出局。同樣,我這裡做的處理是,先將上一輪最後乙個報數的編號移動到最前面,即17、23、5、11;然後開始第三輪報數,未出局的編號為17,此時鍊錶中僅剩乙個節點,故程式結束。

**如下

/**

* 核心資料結構:雙鏈表

*/public int getresult(int n)

while (list.size() > 1)

else

}round++; // 下一輪的最大報數

curr = 0; // 表示還未開始報數

if (list.size() > 1)

}return list.pop();// 返回最後乙個元素

}

演算法題目 約瑟夫環問題

題目 0,1,n 1這n個數字排成乙個圓圈,從數字0開始每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。解法一 經典解法,用環形鍊錶模擬圓圈。這種方法每刪除乙個數字需要m步運算,總共有n個數字,因此總的時間複雜度是o mn 同時這種思路還需要乙個輔助鍊錶來模擬圓圈,其空間複雜度是o...

演算法題目 約瑟夫環問題

題目 0,1,n 1這n個數字排成乙個圓圈,從數字0開始每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。解法一 經典解法,用環形鍊錶模擬圓圈。這種方法每刪除乙個數字需要m步運算,總共有n個數字,因此總的時間複雜度是o mn 同時這種思路還需要乙個輔助鍊錶來模擬圓圈,其空間複雜度是o...

約瑟夫環問題 遞迴推導

題目描述 n個數,編號為 0 1,n 1 排成乙個圓圈,從數字 0 開始,每次從這個圓圈中刪除第 m 個數,請問最後乙個剩下的數是多少?推導過程 定義乙個函式f n,m 為 n 個數中取 m 最後剩下的編號。第乙個被刪除的數是 m 1 n,記為 k 此時因為序列已經不連續,函式可以定義為f n 1,...