【LeetCode & 劍指offer刷題】發散思維題3:62 圓圈中最后剩下的數字(約瑟夫環問題)


【LeetCode & 劍指offer 刷題筆記】目錄(持續更新中...)

62 圓圈中最后剩下的數字(約瑟夫環問題)

 

題目描述

每年六一兒童節,牛客都會准備一些小禮物去看望孤兒院的小朋友,今年亦是如此。HF作為牛客的資深元老,自然也准備了一些小游戲。其中,有個游戲是這樣的:首先,讓小朋友們圍成一個大圈。然后,他隨機指定一個數m,讓編號為0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然后可以在禮品箱中任意的挑選禮物,並且不再回到圈中,從他的下一個小朋友開始,繼續0...m-1報數....這樣下去....直到剩下最后一個小朋友,可以不用表演,並且拿到牛客名貴的“名偵探柯南”典藏版(名額有限哦!!^_^)。請你試着想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)
 
方法一:用數組模擬過程(也可以用鏈表模擬)
/*
約瑟夫環問題
方法一:用數組模擬過程,刪除之后剩下的元素即為最后結果(可用狀態數組)
81ms,有點慢
O(nlogm(n)), O(n)
*/
class Solution
{
public :
    int LastRemaining_Solution ( int n , int m )
    {
        vector < int > state ( n , 1 ); //定義一個數組存儲各元素的狀態
        int count_del = 0 ; //對刪除的數字計數
        int count = 0 ; //用於數哪個數被刪除
        int i = 0 ; //索引
        for (; count_del < n ; i ++)
        {
            if ( i == n ) i = 0 ;
            if ( state [ i ] == 1 ) count ++;
            if ( count == m ) //第m個數時進行“刪除”
            {
                count = 0 ;
                count_del ++;
                state [ i ] = 0 ; //更改狀態,0表示已經被刪除
            }
        } //退出循環時,最后一個元素狀態被置0,i++會執行一次,故應返回i-1
        return i - 1 ;
    }
};
 
方法二:找遞推公式
 
現在先將n個人按照編號進行排序: 
0 1 2 3 … n-1 
那么第一次被淘汰的人編號一定是K-1(假設K < n,若K > n則為(K-1) mod n)。將被選中的人標記為”#”: 
0 1 2 3 … K-2 # K K+1 K+2 … n-1 
第二輪報數時,起點為K這個候選人。並且只剩下n-1個選手。假如此時把k看作0’,k+1看作1’… 
則對應有:
0 1 2 3 ... K- 2 # K K+1 K+2 ... n-1
n-K ' n-2' 0 ' 1' 2 ' ... n-K-1'

 

此時在0’,1’,…,n-2’上再進行一次K報數的選擇。假設f[n-1]的值已經求得,因此我們可以直接求得當選者的編號s’。 
但是,該 編號s’是在n-1個候選人報數時的編號,並不等於n個人時的編號 ,所以我們還需要將s’轉換為對應的s。 
通過觀察, s和s’編號相對偏移了K,又因為是在環中,因此得到 s = (s'+K) mod n。 
f[n] = (f[n-1] + k) mod n
 
/*
方法二:推出遞推公式(動態規划)
i = 1, res =0
i = 2, res = (0+3)%2 = 1
i = 3, res = (1+3)%3 = 1
i = 4, res = (1+3)%4 = 0
...
O(n),O(1)
*/
class Solution
{
public :
    int LastRemaining_Solution ( int n , int k )
    {
        if ( n < 1 || k < 1 ) return - 1 ; //返回-1表示非法輸入
       
        int   last = 0 ;
        for ( int i = 2 ; i <= n ; i ++)
            last = ( last + k ) % i ; //i個人時刪除數的索引等於i-1個人時刪除數的索引+k(再對i取余)
       
        return last ;
    }
};
 

 


免責聲明!

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



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