結合力扣題目 第k個排列,學習康托展開和逆康托展開

2021-10-03 12:49:51 字數 1985 閱讀 9155

結合力扣第60題,第k個排列,進行康托展開和逆康托展開的學習。

題目描述:給出集合[1,2,…,n],其所有元素有n!種排列,按大小排列出所有情況,並一一標記,當n=3時,排列如下:

「123」

「132」

「213」

「231」

「312」

「321」

給定n和k,返回第k個排列

如n=3,k=3 則返回"213"

講述康托編碼之前,需要先學習一下康托展開,康托展開是乙個全排列到自然數的乙個雙射,說白了就是將一堆數從小到大排列,然後計算比某個排列數小的排列數有多少個,或者加1來計算某個排列數所在的位置。

公式:ai,表示的是比當前所在位數i的數字小的,並且還未使用的數字的個數,有點拗口哈,舉個例子:

給定n=5,即集合(1,2,3,4,5),給定排列34152,求比它小的排列有多少(或者說求該數值排在第幾個,即求x+1)。

第乙個數3,第5位數,即n=5,比他小的有1和2,2個,所以an = a5 = 2;

第二個數4,第4位數,即n=4,比他小的有1,2,3,有3個數字,但是反看上一位數字是3,所以1和2必定會被使用乙個,所以只剩下1,3或者2,3可以選,這兩種情況可選的數字個數都為2,所以an=a4=2,通過這裡再來理解ai的意思,比所在位數4的數字4小,並且還未被使用的數字(1,3或者2,3)的個數

第三個數字1,第3位,即n=3,比1小的數的個數為0,所以an=a3=0;

第四個數5,第2位,即n=2,比他小的有1,2,3,4四個數,但是第乙個數3,比他小的為1,2,使用了其中乙個,第二個數4,比他小的為1,2,3,會使用1,3或者2,3兩個,這樣下來1,2,3全部都被使用,所以比5小的數字就剩4這個數字,所以比5下的數字的個數為1,即an=a2=1;

最後乙個數2,第1位,即n=1,比2小還未使用的數字個數為0,所以an=a1=0

根據公式得x=2×(5-1)!+2×(4-1)!+0×(3-1)!+1×(2-1)!+0×(1-1)!=61,所以比34152小的數有61個,它所在的位置即61+1=62

既然康托展開是個雙射,那麼它也可以根據x(位置,或者第幾大的排列號)和n,反向求出該排列數。

還是上面的例子,知道x=61(或者知道該排列數在第62位,那麼比他小的就有62-1=61個),和n=5的情況下,求出該排列數34152

61/(5-1)! 得2 餘13 ,所以可以知道,比他小的數有2個,那麼第乙個數為3;

13/(4-1)! 得2 餘1,所以比第二個數小的也有兩個,但是3已經被選用了,所以該數為4(比4小的為1和2,兩個數);

1/(3-1)! 得0餘1,比第三個數小的數的個數為0,所以該數為1;

1/(2-1)! 得1餘0,所以比第四個數小的數的個數為1,由於1,3,4均已經使用,所以只剩下2和5,從未使用的數字中選擇,所以該數為5(2比5小,所以比他小的數的個數為1,如果該數為2,那麼比他小的數為0)

最後剩下乙個數2。

所以綜上,得出結果34152

懂了康托展開和逆康托展開後,再來看剛開始那道題,就容易了,直接使用逆康托展開即可,**如下:

在這裡插入**片

class

solution

:def

getpermutation

(self, n:

int, k:

int)

->

str:

import math

res=

"" n_list=

[str

(i)for i in

range(1

,n+1)]

k=k-

1while n>0:

n=n-

1 a,k=

divmod

(k,math.factorial(n)

) res+=n_list.pop(a)

return res

LeetCode 第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 ...

力扣 060 第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 ...

Leetcode題目60 第k個排列

給出集合 1,2,3,n 其所有元素共有 n 種排列。按大小順序列出所有排列情況,並一一標記,當 n 3 時,所有排列如下 123 132 213 231 312 321 給定 n 和 k,返回第 k 個排列。說明 給定 n 的範圍是 1,9 給定 k 的範圍是 1,n 示例 輸入 n 3,k 3 ...