Leetcode演算法——60、排列序列(permutation sequence)
阿新 • • 發佈:2018-12-20
集合 [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))