最簡化約瑟夫環問題的遞迴演算法詳細解析

2021-08-09 15:03:52 字數 2512 閱讀 6564

這個問題可能每個學演算法的同學都會遇見,我沒那麼聰明,第一次看見時做不出來,只發現一些規律,後面看到演算法也挺久才看懂,這裡是將別人的演算法結果做乙個解析,例子是暫時網上找的遞迴最簡潔的例子:

下面就以這個例子做乙個解析,這個解法的實際問題就是n個東西圍成乙個圈,從一開始叫到m號的東西出去,求最後剩下的編號。(演算法面試極為常見,就想知道你遞迴學的怎麼樣,就少用模擬法什麼的了)

我們肯定一眼是無法進行乙個通項函式的建立的,m=1的時候是個例外,剩下的是最後乙個,但我們知道前乙個和後乙個是有一定關係的,以前上課的時候老師說這個叫解題思路或者方向。

其中變數有兩個乙個是人數n,乙個是標號數m。所以我們求的問題函式就是f(n,m),而標號數是固定的,每次計數的時候都是這個標號,所以這樣我們的思路就可以建立起來了。

首先是首項f(1,m)=0,也可以直接理解為已經完成結果留下來的就是1號,這裡不影響。

然後是第2項f(2,m),這裡就要看是單數還是雙數了,所以就可以用取餘數計算 2%m,m是雙數留下的就是1,m是單數留下的就是2。

然後是第3項f(3,m),到這裡的時候大家就知道就不光是單雙的關係了比如m=2,留下的是3;m=3,留下的是2;m=4,留下的是2;m=5,留下的是1;m=6,留下的是1,m=7,留下的是3;等等然後再和第2項對應一下,看有什麼規律,如下表:一眼看不出規律吧,沒關係我們看看第三項是如何計算的,這個時候我們我要考慮隊伍重置問題了,還是舉簡單的例子,當n=3,m=2時,第一輪編號都是123,用n除m,這裡餘1,也就是這一行這一圈的計數已經完成了,出局的是2,而這個2和m的關係很明顯,餘數是等於0的,所以這一圈結束了之後我們還有兩個人,還要繼續報數,那後面剩了多少人呢,也就是餘數,1個(3號),所以下一圈的報數就是這樣,3 1,但是他們的編號已經改變了,3變成1號,1變成2號,也就是n=2了,這個時候就回歸到了第2項,這裡m是雙數,留下的就是1號,而1號現在是3,所以f(3,2)就是3了,這裡的遞迴就完成了,後面怎麼加都是一樣的,最終都將回歸到f(2,m)來得到答案,然後下一步知道原理了,就開始建立演算法了,下面表是不是看起來很有規律,當然是有規律的,不過要從這個規律去解題,恐怕是一條不歸路。

m        2    3    4    5    6    7    8    9    10    11    12

第2項     1    2    1    2    1    2    1    2     1      2      1    

第3項     3    2    2    1    1    3    3    2     2      1      1

這裡就開始演算法的建立了,這個看個人思維了,有人有高效的思維就其實是因為他高效和低效的方法都知道,自然能直接選擇高效的方法,多學習多思考吧。

首先列兩個方程 

f(1,m) =0;這裡上面提過了,主要就是求f(n,m)和f(n-1,m)的對應關係了。

最簡單的f(2,m)應該是多少,從上面的演算法知道留下的應該是m%2,那這樣結果就是0或者1,那我們需要返回的是1或者2這個之間數,這個很簡單,加乙個1就行,這個問題一定要考慮到,所以

f(2,m)=m%2+1 。

然後是f(3,m)=(f(2,m)-1+m)%3 + 1   , 這裡加一減一原因和上面一樣,加m是因為對錶進行重置,是上層表加m做下層表的計算,比如f(2,3) n=2,m=3,m%2+1就是留下來的數其中f(2,3)-1=0,那麼f(3,3) n=3,m=3 就是第一輪1,2,3 ;第二輪1,2,1,2,是不是就是f(2.3)的重複(兩個值交替出現)。那再往下推,f(4.3)第一輪,1,2,3,4;

第二輪;1,2,4,1,2,4這個時候是不是又和上面一樣了,三個值交替出現,第三輪,1,2,1,2換算成公式,r2= m%2, r3=(r2 +m)%3, r4=(r3+m)%4,這個r就是在m定值下取的餘數舉個例子大家就知道了,當m=3時,n=2時,r2=1 ,那n=3的時候我們把這個r2=1加到上面也就是r3=(3+1)%3=1 說明餘了乙個數,那留下來的就是2號,然後我們在返回來推,在n=3時是1,2,3中的餘數是0,留下來的就是1,2繼續餘就是1,留下來的就是2,那這裡最後的餘數是1,而r2+1=2=f(2,3)

那演算法就建立好了我們帶入檢查一下吧,  這個時候就可以對照上面的表了,隨機選兩個值,f(2,3)=2, f(3,3) = (2-1+3)%3 +1 =2,嗯這一組正確;

下一組,f(2,7)= 2, f(3,7) =(2-1+7)%3 +1 =3   ,嗯也正確,

最後一組,f(2,12) =1, f(3,12) = (1-1+12)%3+1 =1 ,ok沒有問題,那說明約瑟夫環的遞迴公式我們已經推導出來了。

然後就是寫入程式,其實有上面的公式再看下面的就很好理解了。

最終該問題的遞迴公式為

f(2,m)=m%2+1

f(3,m)=(f(2,m)-1+m)%3 + 1

f(n,m)=(f(n,m)-1+m)%n + 1

package test;

public class cl

system.out.println(r+1);

} public static void main(string args)

}

約瑟夫環 遞迴演算法

假設下標從0開始,0,1,2 m 1共m個人,從1開始報數,報到k則此人從環出退出,問最後剩下的乙個人的編號是多少?現在假設m 10 0 1 2 3 4 5 6 7 8 9 k 3 第乙個人出列後的序列為 0 1 3 4 5 6 7 8 9 即 3 4 5 6 7 8 9 0 1 我們把該式轉化為 ...

約瑟夫環之遞迴演算法

問題描述 約瑟夫環是乙個數學的應用問題 已知n個人 以編號1,2,3 n分別表示 圍坐在一張圓桌周圍。由第乙個人開始報數,數到m的那個人出列 他的下乙個人又從1開始報數,數到m的那個人又出列 依此規律重複下去,直到最後剩下乙個人。一般的思路就是通過乙個count計數的方法,迴圈遍歷鍊錶,逐一刪除。但...

約瑟夫環問題 遞迴推導

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