LeetCode 🟡 1823. Find the Winner of the Circular Game
🔗 🟡 1823. Find the Winner of the Circular Game 1412
tags: Weekly Contest 236
陣列(Array)
模擬(Simulation)
佇列(Queue)
遞迴(Recursion)
數學(Math)
題意
有 個人正在玩一個遊戲。所有人坐成一圈,按照 順時針順序 從 到 編號。從第 個人順時針移動一位會到達第 個人的位置,其中 ,而從第 個人順時針移動一位會回到第 個人的位置。
遊戲規則如下:
- 從第 個人所在位置開始。
- 沿著順時針方向數 個人,計數時需要 包含 起始時的那位,被數到的人會離開圓圈並視為輸掉遊戲。
- 如果圓圈中仍然有不止一個人,從剛剛輸掉的人的 順時針下一位 開始,回到步驟 繼續執行。
- 否則,圓圈中最後一個人獲勝。
給定參與遊戲的人數 和整數 ,請返回遊戲的獲勝者編號。
思路
方法一:模擬(Simulation) + 佇列(Queue)
根據題意,最直觀的方式就是使用 佇列(Queue) 來 模擬(Simulation) 遊戲過程。在每一輪遊戲中,我們從佇列的前端取出 個人,並將他們依次加到佇列的尾部,最後將 第 個人,也就是佇列前端的人移出。重複這個過程直到佇列中只剩下一個人,即為獲勝者。
複雜度分析
- 時間複雜度:,每一輪遊戲需要移動 個人,並移除 個人,總共需要進行 輪。
- 空間複雜度:,使用了一個佇列來存儲所有參與遊戲的人。
1 | class Solution: |
1 | class Solution { |
方法二:約瑟夫問題(Josephus Problem) + 遞迴(Recursion)
事實上,這個問題是經典的數學問題,稱為 約瑟夫問題(Josephus Problem) ,可以使用遞迴的方式來解決這個問題。
令 表示有 個人參與遊戲,每次數 個人,最後獲勝者的位置,此處先以 來表示位置。根據遞迴的思路,我們可以通過以下公式來計算 :
- 若 ,則獲勝者的位置為 ;
- 若 ,則獲勝者的位置可以通過上一次遊戲的獲勝者位置和 的關係推算出來:。具體推導過程可以參考參考資料中的連結。
由於我們的數字是從 到 而不是從 開始,因此需要在取模之前先減去 ,最後再加上 。修改後的公式如下:
- ;
- 。
根據 的公式,使用遞迴的方式即可求解出最終的答案。
複雜度分析
- 時間複雜度:,需要遞迴 次來求解最終的答案。
- 空間複雜度:,遞迴過程中使用的堆疊空間。
1 | class Solution: |
1 | class Solution { |
方法三:約瑟夫問題(Josephus Problem) + 迭代(Iteration)
同樣地,根據 的公式,我們可以使用 迭代(Iteration) 的方式來求解最終的答案。
初始化答案 ,從 開始遍歷 ,每次更新答案 。
最後返回 即可。
複雜度分析
- 時間複雜度:,需要遍歷 次來求解最終的答案。
- 空間複雜度:。
1 | class Solution: |
1 | class Solution { |
參考資料
寫在最後
Cover photo is remixed from @吃肥皂泡泡, thanks for their work!
本部落格所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 十六個天亮!
評論
WalineGiscus