深入理解約瑟夫環問題

2021-10-05 03:55:45 字數 1966 閱讀 2009

1 什麼是約瑟夫環問題?

約瑟夫,是乙個古猶太人,曾經在一次羅馬叛亂中擔任將軍,後來戰敗,他和朋友及另外39個人躲在一口井裡,但還是被發現了。羅馬人表示只要投降就不死,約瑟夫想投降,可是其他人堅決不同意。怎麼辦呢,他想到乙個主意:

讓41個人圍成乙個圓圈,從第乙個人開始報數,數到3的那個人被旁邊的人殺死。這樣就可以避免自殺了,因為猶太人的信仰是禁止自殺的。結果一群人殺來殺去最後只剩下兩個了,就是約瑟夫和他朋友,於是兩人愉快地去投降了。

約瑟夫和朋友站在什麼位置才保住了性命呢,這就是我們今天要講的約瑟夫環問題。

2 問題的重要性

這是個bat常用面試題,而且本質上是乙個遊戲,可以廣泛應用於生活中,工作生活好幫手就是它了。

3 約瑟夫環抽象問題

模擬流程:

假如有5個人報數,報到3被殺,情況如下

a   b  c1  d  e  (初始位置,c第乙個被殺)

d   e  a2  b  (c死後的第二次排位,a第二個被殺)

b   d  e3  (a死後的第三次排位,e第三個被殺)

b4 d  (e死後的第四次排位,b第四個被殺)

d   (d留在了最後,初始位置是4)

解決方法:

1 迴圈遍曆法

public static int josephus(int n, int m)

if (people[index] == -1)

count++;  //報數

if (count == m)

}return index;

}

將41傳入方法後,可得結果為30, 因為是從0開始計數,所以等價於現實世界的第31位。

如果約瑟夫也用這種常規方式去解決問題,那麼就無法快速計算出自己應該站的位置了,所以一定有更簡方法,那就是"遞迴法"。

2 遞迴法

模擬流程(第一種情況和上邊表述相同):

假如有5個人報數,報到3被殺,情況如下

0   1   2    3   4  (假設從0開始計算位置)

a   b  c1  d  e  (初始位置,c第乙個被殺)

d   e  a2  b  (c死後的第二次排位,a第二個被殺)

b   d  e3  (a死後的第三次排位,e第三個被殺)

b4 d  (e死後的第四次排位,b第四個被殺)

d  (d留在了最後,初始位置是3)

假如有4個人報數,報到3被殺,情況如下

0   1    2    3  

a   b  c1  d(初始位置,c第乙個被殺)

d   a  b2  (c死後的第二次排位,b第二個被殺)

d3 a  (b死後的第三次排位,d第三個被殺)

a  (d留在了最後,初始位置是0)

可以看到,n個人報數,死掉乙個人後,變成了n-1個人報數的問題,和n-1個人直接報數的區別只在於下角標。那我們來看一下下角標使怎麼變化的?我們把重新排位前的位置叫old,新的位置叫new, 則情況如下:

old   new

d  3  -> 0

a   0 -> 1

b   1 -> 2

old = (new + 3)%4   -- 為了不超過n本身  對n取模

old等價於f(n,m), n個人報數m的情況, 而new等價於f(n-1,m),即為n-1個人報數m的情況。

則最終公式為  f(n,m) = (f(n-1,m) + m)%n

遞迴:是把複雜問題遞推為最簡問題,然後將結果回歸的過程。

步驟:找規律 &  找出口

則編寫**如下。

public static int josephusbyrec(int n, int m)

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

}

4  總結

這是發生在公元66到67年間的故事,是乙個來自2023年前古人的智慧型,追古思今,你學會了嗎?

理解 約瑟夫環

總結了個小經驗,有時候光靠看是看不出什麼端倪來的,還必須得動下筆,比劃比劃也許就那麼簡單 include include typedef struct node node node creatlist int n 建立乙個含 n個人的迴圈鍊錶 p next head 構建迴圈鍊錶 return he...

詳解約瑟夫環問題 C C

約瑟夫問題 n個人圍坐成一圈,從1開始順序編號 遊戲開始,從第乙個人開始由1到m迴圈報數,報到m的人退出圈外,問最後剩下的那個人原來的序號。問題分析 面對這樣迴圈報數的資料,我們最容易想到的就是用陣列進行報數的模擬,最後把存活的人的編號輸出。先貼上這種思路的 1 include2 include3 ...

JAVA求解約瑟夫環

與前面我們介紹的大多數程式問題一樣,約瑟夫環問題也是來自於乙個故事。這個故事發生在乙個名叫約瑟夫的猶太人身上,據說在羅馬人占領喬塔帕特後,39 個猶太人與約瑟夫及他的朋友躲到乙個洞中,39個猶太人決定寧願死也不要被敵人到,於是決定了乙個自殺方式,41個人排成乙個圓圈,由第1個人 開始報數,每報數到第...