leetcode 第k個排列 python

2021-08-25 22:14:14 字數 3020 閱讀 9658

題目描述:*給出集合 [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 的範圍...