[LeetCode]約瑟夫環問題(劍指offer62)


約瑟夫環問題是一個經典的數學問題,背景故事參考百度百科,其原始問題如下:

0,1,,n-1這n個數字排成一個圓圈,從數字0開始,每次從這個圓圈里刪除第m個數字。求出這個圓圈里剩下的最后一個數字。

比較直接的想法是通過鏈表模擬游戲,直到最后只剩一個元素,但這樣的時間復雜度是O(nm),顯然不行。類似問題通過數學方法找到規律會簡單的多,其實很多遞歸以及動態規划題目也是通過數學方法找遞推式即可簡單解出。

記上述問題的解為f(n,m)。則第一個被刪除的數為(m-1)%n。此時,轉化為由m%n開始的,規模為(n-1,m)的相同問題結構約瑟夫環問題。所以此問題可以通過遞歸來求解,但要知道每次迭代之后,新元素和就元素的一一對應關系。以第一次迭代為例:

把新元素編號記為x,舊元素編號記為y,那么新舊編號的對應公式為

y = (x + m) % n

由此可得

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

f(1,m) = 0

public int lastRemaining(int n, int m) {
    int f = 0;
    for (int i = 2; i <= n; i++) {
        f = (f + m) % i;
    }
    return f;
}

其中f是f(1,m)的解。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM