牛客網(面試題)

孩子們的遊戲(圓圈中最後剩下的數)

每年六一兒童節,牛客都會準備一些小禮物去看望孤兒院的小朋友,今年亦是如此。HF作爲牛客的資深元老,自然也準備了一些小遊戲。其中,有個遊戲是這樣的:首先,讓小朋友們圍成一個大圈。然後,他隨機指定一個數m,讓編號爲0的小朋友開始報數。每次喊到m-1的那個小朋友要出列唱首歌,然後可以在禮品箱中任意的挑選禮物,並且不再回到圈中,從他的下一個小朋友開始,繼續0…m-1報數…這樣下去…直到剩下最後一個小朋友,可以不用表演,並且拿到牛客名貴的“名偵探柯南”典藏版(名額有限哦!!_)。請你試着想下,哪個小朋友會得到這份禮品呢?(注:小朋友的編號是從0到n-1)

package client;

public class Solution {
    public int LastRemaining_Solution(int n, int m) {
    // 如果有n個小朋友,那麼return -1
    	if(n==0)return -1;
    	// 想想成爲 把小朋友手拉手,即爲一個環形鏈表
           Node root =  getNodeLink(n);
           // root的前驅節點
           Node  r = null ;
           /*當環的下一個節點不是自己的時候,即就是環裏面只剩自己,
           那麼這個節點即爲所要求的節點,
           退出while循環,*/
           while(root.next!=root){
           /*這裏爲什麼是m-2,不是m-1;因爲 這是單向循環鏈表,
           我們要想當前節點消失,那麼循環停止時需要停到當前節點的前一個節點
           ,顧循環應該少循環一次*/
               for(int i =0;i<=m-2;i++){
               // r始終爲root的前驅節點
            	   r  = root;
            	   root = root.next;
                  
               }
               /* 需要刪除的節點的前一個節點的next指針指向 當前節點的下一個節點,
               即就是刪除了該節點*/
               r.next = root.next;
               /* 當前節點需要指向自己的下一級節點,因爲 刪除了 當前節點,下一次 
               開始數數的就是當前節點的下一個節點,即就是題中高亮部分從下一個小朋友開始 */
               root = root.next;
           }
           //返回最後的數據
           return root.num;
          
    }

   public static Node getNodeLink(int n){
        Node root = new Node();
        Node curr = root;
        curr.num = 0;
        for(int i=1;i<n;i++){
          Node node = new Node();
          node.num = i;
          curr.next = node;
          curr = node;
        }
       curr.next = root;
       return root;
    }
    public static void main(String[] args) {
		int lastRemaining_Solution = new Solution().LastRemaining_Solution(6, 6);
		System.out.println(lastRemaining_Solution);
	}
}
    class Node{
       public Node next;
       public int num;
    }

運行結果:

在這裏插入圖片描述

思索過程:

  • 讀到這個題的時候,我就想到這個一個約瑟夫環問題,數據結構沒有白學~~,然後就想着把這個問題轉化成小朋友手拉手的問題,也就是 形成一個 單向循環鏈表,緊接着就是數數,數數可以想象成一個for循環,一次固定 循環 m-1次,即就是循環 0~m-1次(注意:代碼部分寫的是m-2,已經解釋過了,此處不再囉嗦),在循環內,指針不斷移動,for循環出來,指針移除當前節點,進行轉換操作。代碼整個部分,我們不用關心哪個小朋友數哪個數把小朋友數數就想像成在每一輪的循環裏 執行指針後移操作,這道題便迎刃而解了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章