leetcode 第k個排列 python
阿新 • • 發佈:2018-11-10
60. 第k個排列
題目描述:*給出集合 [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”*
1. 暴力法
可以用遞迴全排列,將所有的可能都加入到一個列表中,進行排序,找到第K個就行了,這裡就不做多述,因為時間複雜度太高了,肯定超時。
2.權值解法
有點像海明碼的感覺,以n=6,k=100為例,我們來定義一下他們的權值,下面我們來看張圖片
當第六位確定之後,後面五位數最多能組成120個數(5!),也就是說圖上6所在的位置,1代表120,2代表240,以此類推。我們定義圖上6所在的位置的權值為120,當確定左邊兩位的時候,剩下四位最大可能組合為24種,我們定義其權值為24,剩下的就不一一說了,看上面的圖。
下面我們來舉個例子n=6,k=100;
首先n=6最大組合數是720,720>100說明6位數的組合數超過100,假定我們確定最高位為1,
剩下的五位數最大組合數為120,120>100同理說明五位數的組合數超過100,同理我們可以判斷四位數不行。大家都知道當確定位數後,最高位越小這個數越小,所以證明上面的假定成立,最高位為1。下面就不一一解說了,次高位權值為24,在剩下的數中【2,3,4,5,6】選取6
這個程式碼的思路較清晰但是在LeetCode不能正常執行不知道是什麼原因,我試過了window系統上的python2.X、python3.X和Linux終端都能正常執行。我猜測是取天花那一步出問題了,如果你們有興趣可以加個if判斷,我就懶得寫了,之後我再複製一個我好早之前寫的程式碼,有點不清晰,但是能通過用時LeetCode上用時28ms。
import math
class Solution(object):
def getPermutation(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
templist=[]#定義一個列表,用於裝放下面取出的數
temp=[i for i in range(1,n+1)]#定義一個n位的列表1-n
dicts={1:1,2:1,3:2,4:6,5:24,6:120,7:720,8:5040,9:40320,10:362880}#定義各位的權值
for i in range(n,0,-1):
s = math.ceil(k / dicts[i])#計算商值 取其天花
templist.append(temp.pop(s - 1))#將對應數值,加入到templist中,並刪除在temp中取出得數,避免重複取出
if k%dicts[i]==0:#判斷能整除
templist.extend(temp[::-1])#將剩餘數反轉,即最大組合數
break
else:#如果不能整除,即將k值等於其餘數
k%=dicts[i]
return ''.join([str(i) for i in templist])#將列表中數字先轉化為str`
程式碼二
class Solution(object):
def getPermutation(self, n, k):
"""
:type n: int
:type k: int
:rtype: str
"""
templist=[]
temp=[i for i in range(1,n+1)]
dicts={1:1,2:2,3:6,4:24,5:120,6:720,7:5040,8:40320,9:362880,10:3628800,11:39918600}
for i in range(n-1,0,-1):
if k<=dicts[i]:
templist+=temp[:len(temp)-i]
temp=temp[len(temp)-i:]
else:
if k==dicts[i+1]:
templist.append(temp[k//dicts[i]-1])
temp.pop(k//dicts[i]-1)
templist+=temp[::-1]
temp=[]
break
else:
templist.append(temp[k // dicts[i]-1 if k%dicts[i]==0 else k // dicts[i] ])
temp.pop(k // dicts[i]-1 if k%dicts[i]==0 else k // dicts[i])
k = k % dicts[i]
if k==0:
templist += temp[::-1]
temp = []
break
s1=''
for s in templist+temp:
s1+=str(s)
return s1