求排列中第k大的數 逆康托展開

2021-06-24 11:41:49 字數 1016 閱讀 3670

我想到了這種方法,但是不知道這就是逆康托展開,然後搜了下,如下:

**:簡單介紹下:

這個方法還是用例子來說比較好

例1 的全排列,並且已經從小到大排序完畢

(1)找出第96個數

首先用96-1得到95

用95去除4! 得到3餘23

用23去除3! 得到3餘5

用5去除2!得到2餘1

用1去除1!得到1餘0

有3個數比它小的數是4

所以第一位是4

有3個數比它小的數是4但4已經在之前出現過了所以是5(因為4在之前出現過了所以實際比5小的數是3個)

有2個數比它小的數是3

有1個數比它小的數是2

最後乙個數只能是1

所以這個數是45321

(2)找出第16個數

首先用16-1得到15

用15去除4!得到0餘15

用15去除3!得到2餘3

用3去除2!得到1餘1

用1去除1!得到1餘0

有0個數比它小的數是1

有2個數比它小的數是3 但由於1已經在之前出現過了所以是4(因為1在之前出現過了所以實際比4小的數是2)

有1個數比它小的數是2 但由於1已經在之前出現過了所以是3(因為1在之前出現過了所以實際比3小的數是1)

有1個數比它小得數是2 但由於1,3,4已經在之前出現過了所以是5(因為1,3,4在之前出現過了所以實際比5小的數是1)

最後乙個數只能是2

所以這個數是14352

例題:

描述現在有"abcdefghijkl」12個字元,將其按字典序排列,如果給出任意一種排列,我們能說出這個排列在所有的排列中是第幾小的。但是現在我們給出它是第幾小,需要

你求出它所代表的序列.

輸入第一行有乙個整數n(0**如下:

#include #include std::vecto***(12);

void init()

int main (int argc,char**argv)

std::cout<

康托展開和康托逆展開解決第K個排列問題

集合包含了 n!種不同的排列,將這n!種排列從小到大進行排序,某個排列為第k 個,求k時,使用康托展開,已知k求對應的排列時,使用康托逆展開。對於某個排列 a1,a2,a3,an 將其存入陣列s 求它在n!個排列中的位置k,用rli表示ai後面比ai小的數的個數,ri表示ai後面的數的個數,k 1 ...

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

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

結合力扣第60題,第k個排列,進行康托展開和逆康托展開的學習。題目描述 給出集合 1,2,n 其所有元素有n!種排列,按大小排列出所有情況,並一一標記,當n 3時,排列如下 123 132 213 231 312 321 給定n和k,返回第k個排列 如n 3,k 3 則返回 213 講述康托編碼之前...