1. 程式人生 > 實用技巧 >【LeetCode/LintCode 題解】約瑟夫問題 · Joseph Problem

【LeetCode/LintCode 題解】約瑟夫問題 · Joseph Problem

n個人按順序圍成一圈(編號為1~n),從第1個人從1開始報數,報到k的人出列,相鄰的下個人重新從1開始報數,報到k的人出列,重複這個過程,直到隊伍中只有1個人為止,這就是約瑟夫問題。現在給定nk,你需要返回最後剩下的那個人的編號。

  • 1<=n<=1000, 1<=k<=100

線上評測地址:LintCode 領釦

樣例1

輸入: n = 5, k = 3
輸出: 4
解釋:
求解過程:
原佇列 :1 2 3 4 5
第一輪: 1 2 4 5 其中 3 出列
第二輪: 2 4 5 其中 1 出列
第三輪: 2 4 其中 5 出列
第四輪: 4 其中 2 出列

樣例2

輸入: n = 5, m = 1
輸出: 5
解釋:
第一輪: 2 3 4 5, 其中 1 出列
第二輪: 3 4 5, 其中 2 出列
第三輪: 4 5, 其中 3 出列
第四輪: 5, 其中 4 出列

【題解】

暴力解決。建立一個連結串列,並在每次迭代中刪除一個節點。O(n)時間複雜度。

public class Solution {
    /**
     * @param n: an integer
     * @param k: an integer
     * @return: the last person's number
     */
    public int josephProblem(int n, int k) {
        List<Integer> list = new LinkedList<>();
        for (int i = 1; i <= n; i++) {
            list.add(i);
        }
        
        int i = 0;
        while (list.size() != 1) {
            i = (i + k - 1) % list.size();
            list.remove(i);    
        }
        return list.get(0);
    }
}
更多題解參見:九章演算法