題目描述:*給出集合 [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(100/24=4點多,所以取第五位),確定兩位後現在我們來確定第三高位,用剩下的(餘數)4(100/24=4…..4)繼續除以其權值6等於零點幾,所以選剩下數列中第一位(2)。再繼續用上次的餘數4除以第四高位的權值2,等於2正好整除,選取剩下列表中的第二位【3,4,5】4,(正好整除的意思就是說在確定前面的高位的基礎上,後面剩餘得數選取他們的最大組合數就行了)所以,第五位第六位分別是5,3。最終我們可以得出第一百個數是(k=100)162453。自認說的不是很清楚,第一次寫部落格,如有疑問或建議歡迎回帖,謝謝。下面直接看**。
這個**的思路較清晰但是在leetcode不能正常執行不知道是什麼原因,我試過了window系統上的python2.x、python3.x和linux終端都能正常執行。我猜測是取天花那一步出問題了,如果你們有興趣可以加個if判斷,我就懶得寫了,之後我再複製乙個我好早之前寫的**,有點不清晰,但是能通過用時leetcode上用時28ms。
import math
class
solution
(object):
defgetpermutation
(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=#定義各位的權值
for i in range(n,0,-1):
s = math.ceil(k / dicts[i])#計算商值 取其天花
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):
defgetpermutation
(self, n, k):
""" :type n: int
:type k: int
:rtype: str
"""templist=
temp=[i for i in range(1,n+1)]
dicts=
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]:
temp.pop(k//dicts[i]-1)
templist+=temp[::-1]
temp=
break
else:
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
LeetCode 第k個排列
給出集合 1,2,3,n 其所有元素共有 n 種排列。按大小順序列出所有排列情況,並一一標記,當 n 3 時,所有排列如下 123 132 213 231 312 321 給定 n 和 k,返回第 k 個排列。說明 示例 1 輸入 n 3,k 3輸出 213 示例 2 輸入 n 4,k 9輸出 23...
Leetcode 第K個排列
給出集合 1,2,3,n 其所有元素共有 n 種排列。按大小順序列出所有排列情況,並一一標記,當 n 3 時,所有排列如下 123 132 213 231 312 321 給定 n 和 k,返回第 k 個排列。首先,我們先理解清楚全排列的過程。給定n 3,則123的全排列有 具體先固定住1,對23進...
LeetCode 第k個排列
部落格說明 介紹60.第k個排列 題目 給出集合 1,2,3,n 其所有元素共有 n 種排列。按大小順序列出所有排列情況,並一一標記,當 n 3 時,所有排列如下 123 132 213 231 312 321 給定 n 和 k,返回第 k 個排列。說明 給定 n 的範圍是 1,9 給定 k 的範圍...