1. 題目
0,1,n-1這n個數字排成一個圓圈,從數字0開始,每次從這個圓圈裏刪除第m個數字。求出這個圓圈裏剩下的最後一個數字。
例如,0、1、2、3、4這5個數字組成一個圓圈,從數字0開始每次刪除第3個數字,則刪除的前4個數字依次是2、0、4、1,因此最後剩下的數字是3。
2. 解題思路
這道題是簡單,我是萬萬沒想到的。
其實本題是著名的約瑟夫環問題
。
2.0 暴力法
就按照題目的思路,用一個變量計數,每到m之後,刪除數組中的一個元素,直到只剩一個元素。但是超時了。
2.1 數學法
3. 代碼實現
3.0 暴力法
class Solution:
def lastRemaining(self, n: int, m: int) -> int:
"""
1. 暴力法, 超時
"""
record = list(range(n)) # 記錄元素
count = 0
while len(record) > 1:
i = 0
while i < len(record) and len(record)>1:
count += 1
if count == m:
del record[i]
count = 0 # 重置爲0
else:
i += 1
return record[0]
3.1 數學法
class Solution:
def lastRemaining(self, n: int, m: int) -> int:
"""
1. 暴力法, 超時
2. 數學法,題解都沒看懂。。
"""
ans = 0;
# 最後一輪剩下2個人,所以從2開始反推
for i in range(2, n+1):
ans = (ans + m) % i
return ans
4. 總結
算法這東西要是涉及到數學知識,那麼真的是難。
5. 參考文獻
[1] 劍指offer叢書
[2] 劍指Offer——名企面試官精講典型編程題