返回第k個排列

2021-08-21 19:25:25 字數 1459 閱讀 4282

給定數字n,易知n一共有n!個排列組合,現在要返回第k個排列(list是以從小到大的順序排列的)。

比如:n=3,k=4,全排列為[123, 132, 213, 231, 312, 321],返回"231"。

使用python中的itertools,很容易就能實現:

def permulation(self, n, k):

nums = [i for i in range(1,n+1)]

list = list(itertools.permutations(nums,n))

return list[k-1]

但是這種做法時間複雜度和空間複雜度極高,當n很大的時候,這種演算法基本不可取!

1、需要乙個list存放1到n的所有數:[1,2,3,...,n]

2、對於每一位上的數字:num = k/(n-1)!  向上取整。

比如:n = 4, k = 7,那麼num = 7 / 3的階乘 = 7/6,向上取整為2,所以第乙個數字應該取list中的2。

因為按順序排列的話,它的排列規則肯定是 [6個1____,6個2____,6個3____,6個4____]。

3、然後list中需要把2位置上的數刪去 (因為1個數只能被選一次)

4、之後 k 要減去 (num-1)*(n-1)!。它的作用是(以n=3,k=6為例):

123,132,213,231,312,321 在第一次迴圈後,已經確定了第乙個數字是3,所以在判斷第二個數字時,其實是在[312, 321]中判斷,所以第二次的k要代表在[312, 321]中的位置,所以需要去掉之前的[123, 132, 213, 231];之前這些數的個數即為(num-1)*(n-1)!。這時的k=2,和之前的6一樣,都代表321。

以此類推……

總體步驟如下(以n=3,k=5為例):

1、[123, 132, 213, 231, 312, 321],n=3,k=5,list=[1,2,3],

num = ceil( k/(n-1)! ) = ceil( 5/2 ) = 3 ( ceil代表向上取整 ) ,list中取「3」

n = n - 1 = 2

k = k - (num-1)*(n-1)! = 5 - 2*2 = 1

2、[312, 321],n=2,k=1,list=[1,2]

num = ceil( k/(n-1)! ) = ceil( 1/1 ) = 1,list中取「1」

n = n - 1 = 1

k = k - (num-1)*(n-1)! = 1

3、最後直接取list中的最後乙個元素「2」,組合成「312」

public class solution 

return 1; }

public string permutation(int n, int k)

return result+v.get(0);

}}

第k個排列

給出集合 1,2,3,n 其所有元素共有 n 種排列。按大小順序列出所有排列情況,並一一標記,當 n 3 時,所有排列如下 123 132 213 231 312 321 給定 n 和 k,返回第 k 個排列。說明 public string getpermutation int n,int k l...

第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個排列

給出集合 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 ...