↓快轉到主要內容
  1. LeetCode/

LeetCode 60: Permutation Sequence

·1 分鐘· ·
LeetCode Hard Math Combinatorics Recursion
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: hard 第一次嘗試:2026-07-29

  • 提交紀錄:Accepted(2026-07-29)→ Wrong Answer(2026-10-13 重寫)

解題思路
#

1..n 的排列依字典序排好,第一位固定之後,剩下的 n - 1 個數有 (n - 1)! 種排法,所以排列被分成 n 塊,每塊 (n - 1)! 個。

把 k 改成 0-indexed:

  • idx = k // (n - 1)!:第 k 個排列在第 idx 塊,第一位就是剩下數字裡第 idx 小的。
  • k %= (n - 1)!:在這一塊裡的位置。
  • 把用掉的數字從候選中拿掉,對剩下的 n - 1 個數重複。

我的嘗試
#

第一次 AC 就是上面的做法。三個月後重寫時沒有維護「剩下的數字」,而是直接把 k // (n-1)! + 1 當成數字輸出,算階乘的函式也寫錯了(乘的是 n - 1),結果位數和數字都不對。例如 n = 3、k = 3:答案是 "213",回傳 "3"。

正確解法
#

from math import factorial

class Solution:
    def getPermutation(self, n: int, k: int) -> str:
        k -= 1                                     # 改成 0-indexed
        digits = [str(i) for i in range(1, n + 1)]
        res = []
        for i in range(n - 1, -1, -1):
            block = factorial(i)                   # 剩下 i 個數的排法
            idx, k = divmod(k, block)
            res.append(digits.pop(idx))            # 用掉的數字要拿掉
        return "".join(res)

複雜度
#

時間 O(n^2)(pop 是 O(n)),n <= 9。空間 O(n)。

要特別避免的錯誤
#

  • k 要先減 1 變成 0-indexed,否則整除會差一。
  • 用掉的數字要從候選拿掉,下一位是在剩下的數字裡選。

面試口說整理
#

第一位固定之後剩下的有 (n - 1)! 種排法,所以把 k 改成從 0 開始,k 除以 (n - 1)! 就知道第一位是剩下數字裡第幾小的,取出來、k 取餘數,再處理下一位。用掉的數字要拿掉。時間 O(n^2)。

相關文章

LeetCode 3518: Smallest Palindromic Rearrangement II
·2 分鐘
LeetCode Hard Math Combinatorics Counting Hash-Table String
LeetCode 3518 解題筆記:回文由左半邊決定,變成「多重集合的第 k 個排列」;逐位試每個字元,用排列數判斷第 k 個落在哪個分支,排列數可以 O(1) 更新
LeetCode 2709: Greatest Common Divisor Traversal
·2 分鐘
LeetCode Hard Math Number-Theory Union-Find Sieve Gcd Array
LeetCode 2709 解題筆記:任兩個 index 都能互通 ⇔ 全部在同一個連通塊;用 SPF 分解質因數,數字跟它的質因數在 Union-Find 裡合併;1 要特別處理
LeetCode 927: Three Equal Parts
·2 分鐘
LeetCode Hard Math Array
LeetCode 927 解題筆記:三段的 1 一樣多,先數 1;第三段一定延伸到陣列尾端,它的長度決定每段要比對的內容,再檢查三段的位置不重疊
LeetCode 952: Largest Component Size by Common Factor
·2 分鐘
LeetCode Hard Math Number-Theory Union-Find Hash-Table Array
LeetCode 952 解題筆記:有共同因數 ⇔ 有共同的質因數;把每個數分解質因數,同一個質因數的 index 用 Union-Find 合併,不用兩兩算 GCD
LeetCode 50: Pow(x, n)
·1 分鐘
LeetCode Medium Math Recursion
LeetCode 50 解題筆記:快速冪,x^n = (x²)^(n/2),n 是奇數時多乘一個 x;n 是負數時算 1 / x^(-n)
LeetCode 509: Fibonacci Number
·1 分鐘
LeetCode Easy Math Dynamic-Programming Recursion Memoization
LeetCode 509 解題筆記:一維 DP 的起點:只需要前兩項,用兩個變數滾動