中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

LeetCode如何求圓圈中最后剩下的數字

發布時間:2021-12-15 14:26:55 來源:億速云 閱讀:132 作者:小新 欄目:大數據

這篇文章主要介紹了LeetCode如何求圓圈中最后剩下的數字,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

                  

題目描述

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

例如,0、1、2、3、4 這 5 個數字組成一個圓圈,從數字 0 開始每次刪除第 3 個數字,則刪除的前 4 個數字依次是 2、0、4、1,因此最后剩下的數字是 3。

  • 1 <= n <= 10^5
  • 1 <= m <= 10^6
                     

題目樣例

                     

示例

  • 輸入: n = 5, m = 3

  • 輸出: 3

  • 輸入: n = 10, m = 17

  • 輸出: 2

                     

題目思考

  1. n 個數字和 n-1 個數字最后剩下的數字有什么關系嗎?
                     

解決方案

                     
思路
  • 一個比較容易想到的思路是暴力法, 即使用數組模擬整個過程: 記錄當前起點, 求要移除的下個數字的下標, 并從原列表中移除它. 但這樣時間復雜度達到了 O(N^2), 因為移除元素也需要 O(N) 時間
  • 而改用雙端鏈表的話則為 O(MN), 因為雖然移除變為了 O(1), 但每次定位下一個要移除的數字下標時不能像數組那樣 O(1) 時間定位, 而是需要 O(M) 時間來遍歷到下個移除的位置
  • 那有什么方法可以做到更小的時間復雜度呢?
  • 如果我們能從 n-1 個數字的結果, 推導出 n 個數字的結果, 那就可以一次遍歷 O(N) 時間搞定
  • 所以嘗試動態規劃的思路, 設                          dp[n, m]是 n 個數字時每次刪除第 m 個數字的最后剩下數字的下標
  • 第一次刪除時, 刪除數字的下標 i 為                          (m-1)%n, 而其下一個下標 i+1 為下一次刪除的起點
  • 此時將新的起點 i+1 映射為下標 0, 自然 i+2 就對應下標 1, ... 到最后原下標 i 就對應映射下標 n-2. 這樣就轉換成了 n-1 個數字時每次刪除第 m 個數字的情況
  • 顯然映射下標 x 與原下標 y 的關系是                          y = (x+i+1)%n, 而 i 為                          (m-1)%n, 所以可以進一步得到                          y = (x+m)%n
  • 下標映射之后, 此時總共有 n-1 個數字, 最終剩余的數字就是                          dp[n-1,m], 這個是映射下標, 根據上面的下標轉換關系, 反推出原下標就是                          (dp[n-1,m]+m)%n
  • 而不管是第一次刪除還是第二次刪除, 其最終剩余的數字只能是同一個,                          所以dp[n, m] = (dp[n-1,m]+m)%n, 這就是最核心的狀態轉移方程
  • 觀察可以發現, 每個 dp 值只和前一個 dp 值相關, 所以我們可以使用一個變量來節省空間, 然后從小到大遍歷到 n 即可
  • 而 dp 初始值為 n=1 的情況, 此時最后剩余的數字顯然只能是 0
                     
復雜度
  • 時間復雜度 O(N): 只需要遍歷到 N
  • 空間復雜度 O(1): 只使用了常數個變量
                     
代碼
class Solution:
    def lastRemaining(self, n: int, m: int) -> int:
        # 初始dp[1,m]為0
        dp = 0
        for x in range(2, n + 1):
            # 對應公式dp[x,m] = (dp[x-1,m] + m) % x
            dp = (dp + m) % x
        return dp

感謝你能夠認真閱讀完這篇文章,希望小編分享的“LeetCode如何求圓圈中最后剩下的數字”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

通辽市| 商都县| 双流县| 陕西省| 阿拉善盟| 怀来县| 太白县| 西充县| 临海市| 西乌珠穆沁旗| 濮阳县| 三河市| 宁远县| 屯门区| 周宁县| 两当县| 壶关县| 偏关县| 铜陵市| 平乐县| 饶平县| 泾川县| 同心县| 乐亭县| 新巴尔虎右旗| 吉安县| 荣成市| 扎兰屯市| 牡丹江市| 连山| 水城县| 长宁区| 美姑县| 成武县| 巨鹿县| 中方县| 土默特左旗| 孟村| 泰来县| 青神县| 吴江市|