Leetcode 60:第k個排列(超詳細的解法!!!)
阿新 • • 發佈:2018-12-12
給出集合 [1,2,3,…,n]
,其所有元素共有 n! 種排列。
按大小順序列出所有排列情況,並一一標記,當 n = 3 時, 所有排列如下:
"123"
"132"
"213"
"231"
"312"
"321"
給定 n 和 k,返回第 k 個排列。
說明:
- 給定 n 的範圍是 [1, 9]。
- 給定 k 的範圍是[1, n!]。
示例 1:
輸入: n = 3, k = 3
輸出: "213"
示例 2:
輸入: n = 4, k = 9
輸出: "2314"
解題思路
首先想到的最簡單的做法就是將所有的排列情況列出來,然後挑選出第k-1
trick
,我們可以不將所有的情況列出,而是通過生成器遍歷
class Solution:
def getPermutation(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
for i, per_list in enumerate(itertools.permutations([i + 1 for i in range(n)])):
if i == k - 1:
return ''.join([str(i) for i in per_list])
如果像下面這樣寫的話就會超時。
class Solution:
def getPermutation(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
per_list = list(itertools.permutations([i + 1 for i in range(n)]))
return ''.join([str(i) for i in per_list[k-1]])
但是這種寫法顯然很爛,我們可以通過遞迴的方法解決這個問題。對於n=4
時,我們實際上會產生如下四種情況:
我們知道對於每種情況都會有(n-1)!
種子集,對於上列來說就是6
種子集。如果k=14
的話,我們知道它一定在
中,並且是
的第二個子集(14-12=2,我們是按照例子中的index
考慮,也就是數列從1
開始。如果按照從0
開始的話,我們輸入就要變成14-1=13
)。我們看
可以分為如下三種情況
我們知道對於每種情況都會有(n-2)!
種子集,對於上列來說就是2
種子集。我們知道它一定是在
中,並且是
的第二個子集,也就是(4,2)
,所以最後的結果就是"3142"
。我們可以非常輕鬆的得到如下遞推公式
邊界問題也非常容易,我們只要考慮n==1
時,返回n_list[0]
即可。
class Solution:
def getPermutation(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
factorials = [1]*(n+1)
for i in range(1, n+1):
factorials[i] = factorials[i-1]*i
n_list = [i for i in range(1, n+1)]
return self.helper(n, k-1, n_list, factorials)
def helper(self, n, k, n_list, factorials):
if n == 1:
return str(n_list[0])
m = k // factorials[n-1]
k %= factorials[n-1]
res = str(n_list[m])
n_list.remove(n_list[m])
res += self.helper(n-1, k, n_list, factorials)
return res
這個問題通過迭代也可以非常快的實現。
class Solution:
def getPermutation(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
factorials = [1]*(n+1)
for i in range(1, n+1):
factorials[i] = factorials[i-1]*i
n_list = [i for i in range(1, n+1)]
k -= 1
res = ''
for i in range(1, n+1):
m = k // factorials[n-i]
k %= factorials[n-i]
res += str(n_list[m])
n_list.remove(n_list[m])
return res
reference:
我將該問題的其他語言版本新增到了我的GitHub Leetcode
如有問題,希望大家指出!!!