1. 程式人生 > >Leetcode演算法——60、排列序列(permutation sequence)

Leetcode演算法——60、排列序列(permutation sequence)

集合 [1,2,3,…,n] 共有 n! 個唯一的排列。

將所有排列方法按照升序排序,可以得到一個序列。
比如 n=3 時的序列為:
“123”
“132”
“213”
“231”
“312”
“321”

要求給定 n 和 k,返回序列中第 k 個排列。

備註:
n 的範圍為 1~9
k 的範圍為 1~9!

示例:

Example 1:
Input: n = 3, k = 3
Output: "213"

Example 2:
Input: n = 4, k = 9
Output: "2314"

思路

分治法。

要求從一共 n! 種排列中,選出第 k 個排列。

這些排列是有規律的:前 (n-1)! 個排列的第1個字元肯定是這 n 個數中的最小值,也就是 1。

比如 [1,2,3,4] 這 4 個數共有 4! 中排列,他們的前 3! 種排列的第1個字元肯定是 1,接下來的 3! 種排列的第1個字元肯定是2 … 直到最後一組 3! 種排列的第1個字元肯定是 4。

一共有 4 組 3! 種排列,即總排列數共有 4*3! = 4! 種。

因此,可以使用分治法,先確定第1個字元,然後遞迴決定剩下的字元。

python實現

    def getPermutation(n, k):
        """
        :type n: int
        :type k: int
        :rtype: str
        分治法。
        """
# 儲存階乘 factorial_list = [1] for i in range(1, n+1): factorial_list.append(factorial_list[-1] * i) def func(digits, k): ''' 找到陣列digits的第k個排列 ''' n = len(digits) if n == 1: # 遞迴結束條件 return
str(digits[0]) first_idx, next_k = divmod(k, factorial_list[n-1]) first = digits.pop(first_idx) return str(first) + func(digits, next_k) return func(list(range(1, n+1)), k-1) if '__main__' == __name__: n = 3 k = 3 print(getPermutation(n, k))