leetcode 60 第K個排列 C C

2021-09-27 12:36:39 字數 1592 閱讀 8853

首先想到46-全排列採用回溯的方法,遞迴呼叫直到第k個數,但該方法時間複雜度過高,存在超時問題。

既然所有的全排列是從小到大,那麼可以對每一位的數字進行定位。當有n位集合時第一位顯然有n個可能,而每乙個第一位確定後,引申出來的可能性有 (n-1)! 個,則對於第一位數字的索引應該是k/(n-1)!。如下所示:

/**

直接用回溯法做的話需要在回溯到第k個排列時終止就不會超時了, 但是效率依舊感人

可以用數學的方法來解, 因為數字都是從1開始的連續自然數, 排列出現的次序可以推

算出來, 對於n=4, k=15 找到k=15排列的過程:

1 + 對2,3,4的全排列 (3!個)

2 + 對1,3,4的全排列 (3!個) 3, 1 + 對2,4的全排列(2!個)

3 + 對1,2,4的全排列 (3!個)-------> 3, 2 + 對1,4的全排列(2!個)-------> 3, 2, 1 + 對4的全排列(1!個)-------> 3214

4 + 對1,2,3的全排列 (3!個) 3, 4 + 對1,2的全排列(2!個) 3, 2, 4 + 對1的全排列(1!個)

確定第一位:

k = 14(從0開始計數)

index = k / (n-1)! = 2, 說明第15個數的第一位是3

更新kk = k - index*(n-1)! = 2

確定第二位:

k = 2

index = k / (n-2)! = 1, 說明第15個數的第二位是2

更新kk = k - index*(n-2)! = 0

確定第三位:

k = 0

index = k / (n-3)! = 0, 說明第15個數的第三位是1

更新kk = k - index*(n-3)! = 0

確定第四位:

k = 0

index = k / (n-4)! = 0, 說明第15個數的第四位是4

最終確定n=4時第15個數為3214

**/

**如下:

class solution ;

//vecto***ctorial = ;

vectorcandidate(n); //陣列candidate記錄候選數字

vecto***ctorial(n+1); //陣列factorial記錄從1到n的階乘

factorial[0] = 1;

for(int i = 1, temp = 1; i <= n; i++)

k = k - 1; //從0開始計數

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

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 示例 1 輸入 n 3,k ...