1. 程式人生 > >【劍指offer系列】 圓圈中最後剩下的數字___45

【劍指offer系列】 圓圈中最後剩下的數字___45

  題目描述:
  把0 ,1 ,……, n-1這n個數排成一個圓圈,從數字0開始,每次從這個圓圈中刪除第m個數字。
  求這個圓圈剩下的最後一個數字
  
  示例:
  輸入:n=3,m=2,即把0 ,1 ,2這三個數字每次刪除第二個,刪除的依次為1, 0,剩下2
  輸出:2
  
  分析:
  經典解法,用環形連結串列模擬圓圈。當連結串列中只有一個節點時,退出。但是這種方法空間複雜度較高
  這裡寫圖片描述 
  
  更高效的解法,分析其中的數學規律。
  在n個數字中,第一個被刪除的是 k = (m-1)%n
  在刪除k個,剩下的n-1個數字為:0, 1 ,…… ,k-1 ,k+1 , ……, n-1
  然後新一輪的計數從k+1開始,即k+1為第一個數字,形成 k+1 , …… ,n-1 ,0 , 1 ,…… k-1。剩下的數字也是n和m的函式。
  將剩下的n-1個數字作一個對映:
  這裡寫圖片描述


  將對映定義為p,則p(x) = (x-k-1)%n。該對映的逆對映為f(x)=(x+k+1)%n。
  對映後的序列和最初的序列具有相同的形式,只是元素個數變為了n-1.
  因此可得到遞推公式:
  這裡寫圖片描述
  
  程式碼:    

int lastRemain(unsigned int n,unsigned int m){
    if(n<1||m<1)  return -1;
    int last=0;
    for(int i=2;i<=n;++i){
        last=(last+m)%i;
    }
    return last
; }

相關推薦

offer系列 圓圈最後剩下數字___45

  題目描述:   把0 ,1 ,……, n-1這n個數排成一個圓圈,從數字0開始,每次從這個圓圈中刪除第m個數字。   求這個圓圈剩下的最後一個數字      示例:   輸入:n

offer系列 從上往下列印二叉樹___23

  題目描述:   給定一棵二叉樹的根節點,按照從上往下的順序列印每一個節點,同一層的節點按照從左往右的順序列印      示例:           分析:   遇到這中涉及到

offer圓圈最後剩下數字,C++實現

一行 AC 個人 ron namespace itl i++ float color 原創博文,轉載請註明出處! # 題目 # 思路 本題即為典型的約瑟夫問題,通過遞推公式解決。 第一行表示每個人的下標,現在要從11個人中刪除報數為3的人,從圖

Offer學習面試題50:樹兩個結點的最低公共祖先

題目:求樹中兩個結點的最低公共祖先,此樹不是二叉樹,並且沒有指向父節點的指標。 樹的結點定義 private static class TreeNode { int val; List<TreeNode> childre

Offer學習面試題36:陣列的逆序對

題目:在陣列中的兩個數字如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數。 舉例分析   例如在陣列{7, 5, 6, 4 中, 一共存在5 個逆序對,分別是(7, 6)、(7,5),(7, 4)

Offer學習面試題38:數字在排序陣列出現的次數

題目:統計一個數字:在排序陣列中出現的次數。 舉例說明 例如輸入排序陣列{ 1, 2, 3, 3, 3, 3, 4, 5}和數字3 ,由於3 在這個陣列中出現了4 次,因此輸出4 。 解題思路   利用改進的二分演算法。   如何用二分查詢演算法

Offer學習面試題3 :二維陣列的查詢

題目:在一個二維陣列中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函式,輸入這樣的一個二維陣列和一個整數,判斷陣列中是否含有該整數。 public class Test03 { /** * 在一個二維陣列中,

Offer學習面試題66:矩陣的路徑

題目:請設計一個函式,用來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中任意一格開始,每一步可以在矩陣中間向左、右、上、下移動一格。如果一條路徑經過了矩陣的某一格,那麼該路徑不能再次進入該格子。 舉例分析   例如在下面的3*

offer系列之二叉樹判斷是否為平衡二叉樹

題目: 平衡二叉樹的性質為:要麼是一顆空樹,要麼任何一個節點的左右子樹高度差的絕對值不超過1。給定一棵二叉樹的頭結點head,判斷這棵二叉樹是否為平衡二叉樹。要求時間複雜度為O(N) 思路:

Offer學習面試題15 :連結串列倒數第k個結點

題目:輸入一個連結串列,輸出該連結串列中倒數第k 個結點.為了符合大多數人的習慣,本題從1 開始計數,即連結串列的尾結點是倒數第1 個結點.例如一個連結串列有6 個結點,從頭結點開始它們的值依次是1 、2、3、4、5 、6。這個個連結串列的倒數第3 個結點是值為

Offer學習所有面試題匯總

tails 超過一半 奇數 正則表達式 detail 刪除 祖先 滑動窗口 翻轉單詞順序 劍指Offer學習   劍指Offer這本書已經學習完了,從中也學習到了不少的東西,現在做一個總的目錄,供自已和大家一起參考,學如逆水行舟,不進則退。只有不斷地學習才能跟上時候,跟得

Offer學習面試題5 : 從尾到頭列印連結串列思路

方案一:(後進先出)遍歷連結串列,再從棧頂開始出個輸出結點的值,此時輸出的結點的順序已經反轉過來了。 先推進棧 再依次取出棧頂元素 方案二:遞迴。 判斷連結串列頭結點是否為空 將 next 結點作為下一次的實參 輸出當前棧頂元素。 缺點:當連結串

offer python面試題7:用兩個棧實現佇列

題目連結 題目描述 用兩個棧來實現一個佇列,完成佇列的Push和Pop操作。 佇列中的元素為int型別。 solution class Solution: def __

offer python面試題8:旋轉陣列的最小數字

題目連結 題目描述 把一個數組最開始的若干個元素搬到陣列的末尾,我們稱之為陣列的旋轉。 輸入一個非減排序的陣列的一個旋轉,輸出旋轉陣列的最小元素。 例如陣列{3,4,5,1,2}為{1,2,

Offer學習所有面試題彙總

劍指Offer學習   劍指Offer這本書已經學習完了,從中也學習到了不少的東西,現在做一個總的目錄,供自已和大家一起參考,學如逆水行舟,不進則退。只有不斷地學習才能跟上時候,跟得上技術的潮流! 目錄 第01-10題 第11-20題 第21-30題

Offer學習面試題4 : 替換空格思路

題目: 請實現一個函式,將一個字串中的每個空格替換成“%20”。例如,當字串為We Are Happy,則經過替換之後的字串為We%20Are%20Happy。 思路: 遍歷的方向兩邊皆可。 若從後往前遍歷,新的字串需要反轉。 用 String 類的方法判斷字串

Offer學習面試題5 : 從尾到頭列印連結串列

題目:輸入個連結串列的頭結點,從尾到頭反過來打印出每個結點的值。 public class Test05 { /** * 結點物件 */ public s

Offer學習面試題26:複雜連結串列的複製

題目:請實現函式ComplexListNode clone(ComplexListNode head),複製一個複雜連結串列。在複雜連結串列中,每個結點除了有一個next 域指向下一個結點外,還有一個sibling 指向連結串列中的任意結點或者null。

Offer學習面試題56:連結串列中環的入口結點

題目:一個連結串列中包含環,如何找出環的入口結點? 解題思路   可以用兩個指標來解決這個問題。先定義兩個指標P1和P2指向連結串列的頭結點。如果連結串列中環有n個結點,指標P1在連結串列上向前移動n步,然後兩個指標以相同的速度向前移動。當第二個指標

Offer學習面試題60:把二叉樹打印出多行

題目:從上到下按層列印二叉樹,同一層的結點按從左到右的順序列印,每一層列印一行。 解題思路   用一個佇列來儲存將要列印的結點。為了把二叉樹的每一行單獨列印到一行裡,我們需要兩個變數:一個變量表示在當前的層中還沒有列印的結點數,另一個變量表示下一次結