0,1,,n-1這n個數字排成乙個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。
例如,0、1、2、3、4這5個數字組成乙個圓圈,從數字0開始每次刪除第3個數字,則刪除的前4個數字依次是2、0、4、1,因此最後剩下的數字是3。
示例 1:
輸入: n = 5, m = 3
輸出: 3
示例 2:
輸入: n = 10, m = 17
輸出: 2
限制:1 <= n <= 10^5
1 <= m <= 10^6
這是乙個約瑟夫環問題。
約瑟夫問題比較難想的點有兩個:
第一點比較好解決,可以通過取餘來完成。
第二點的解決方案是:將刪除結點的後繼作為下一輪的第乙個結點,後續結點依次排列。這樣每輪都是從首結點開始數 m 個了
遞推公式為:f(n, m) = (f(n-1, m)+m) % n
f(n,m)表示還剩n個數時刪除第m個數後得到的index,刪除之後還剩n-1個數。
所以從後往前推。
問題1假設我們已經知道11個人時,勝利者的下標位置為6。那下一輪10個人時,勝利者的下標位置為多少?
答第一輪刪掉編號為3的人後,之後的人都往前面移動了3位,勝利這也往前移動了3位,所以他的下標位置由6變成3。
問題2假設我們已經知道10個人時,勝利者的下標位置為3。那下一輪11個人時,勝利者的下標位置為多少?
答這可以看錯是上乙個問題的逆過程,大家都往後移動3位,所以f(11,3)=f(10,3)+3f(11,3)=f(10,3)+3f(11,3)=f(10,3)+3。不過有可能陣列會越界,所以最後模上當前人數的個數,f(11,3)=(f(10,3)+3)%11f(11,3)=(f(10,3)+3)%11f(11,3)=(f(10,3)+3)%11
class
solution
(object):
deflastremaining
(self, n, m)
:"""
:type n: int
:type m: int
:rtype: int
"""last =
0# 從後往前倒推
for i in
range(2
, n+1)
: last =
(last + m)
% i
return last
面試題62 圓圈中最後剩下的數字
面試題62 0,1,n 1這n個數字排成乙個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。例如,0 1 2 3 4這5個數字組成乙個圓圈,從數字0開始每次刪除第3個數字,則刪除的前4個數字依次是2 0 4 1,因此最後剩下的數字是3。示例 1 輸入 n 5,m...
面試題62 圓圈中最後剩下的數字
1.題目描述 0,1,n 1這n個數字排成乙個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。例如,0 1 2 3 4這5個數字組成乙個圓圈,從數字0開始每次刪除第3個數字,則刪除的前4個數字依次是2 0 4 1,因此最後剩下的數字是3。示例 示例 1 輸入 n...
面試題62 圓圈中最後剩下的數字
題目 0,1,n 1這n個數字排成乙個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後乙個數字。例如,0 1 2 3 4這5個數字組成乙個圓圈,從數字0開始每次刪除第3個數字,則刪除的前4個數字依次是2 0 4 1,因此最後剩下的數字是3。示例 1 輸入 n 5,m 3 ...