leetcode

60. Permutation Sequence

2020-02-25  本文已影响0人  十月里的男艺术家

题目:

60. Permutation Sequence

The set [1,2,3,...,n] contains a total of n! unique permutations.

By listing and labeling all of the permutations in order, we get the following sequence for n = 3:

1. "123"
2. "132"
3. "213"
4. "231"
5. "312"
6. "321"

Given n and k, return the kth permutation sequence.

Note:

Example 1:

Input: n = 3, k = 3
Output: "213"

Example 2:

Input: n = 4, k = 9
Output: "2314"

60. 第k个排列

给出集合 [1,2,3,…,n],其所有元素共有 n! 种排列。

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:

1. "123"
2. "132"
3. "213"
4. "231"
5. "312"
6. "321"

给定 n 和 k,返回第 k 个排列。

说明:

给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。

示例 1:

输入: n = 3, k = 3
输出: "213"

示例 2:

输入: n = 4, k = 9
输出: "2314"

思路:

举例来说明。

n = 4, 参与排列的数字「1, 2, 3, 4」

列出所有的排列

1 + (permutations of 2, 3, 4)

2 + (permutations of 1, 3, 4)

3 + (permutations of 1, 2, 4)

4 + (permutations of 1, 2, 3)

n个数字的排列数为n!,那么3个数的排列数为6。假如k=14,那么第14个排列落在

3 + (permutations of 1, 2, 4)

令k=14-1(减去1是因为程序中索引从0开始), k/(n-1)!= 13/(4-1)! = 2, 在数列「1, 2, 3, 4」中索引为2的数字为3,所以第一个数字为3。

那么问题进一步缩小为「1, 2, 4」数字的排列,求第 k= k%(n-1)!=13%(4-1)=1 个排列:

1 + (permutations of 2, 4)

2 + (permutations of 1, 4)

4 + (permutations of 1, 2)

在这一步中,2个数字排列有2!, 总共有3*2!=6个,我们寻找第一个排列,那么落在

1 + (permutations of 2, 4)

此时 k/(n-2)! = 1/(4-2)! = 0, 即「1, 2, 4」中索引0的数字1。目前我们知道前面两个数字3,1。剩下的数字依次类推。

「2, 4」

k = k % (n-2)! = 1%(4-2)! = 1,第三个数字在「2, 4」中的索引为 k/(n-3)!= 1/(4-3)! = 1,所以第三个数字为4

「2」

k = k % (n-3)! = 1%(4-3)! = 0,第四个数字在「2」中的索引为 k/(n-4)!= 0/(4-4)! = 0,所以第四个数字为2

参考:https://leetcode.com/problems/permutation-sequence/discuss/22507/%22Explain-like-I'm-five%22-Java-Solution-in-O(n)

代码:

class Solution:
    def getPermutation(self, n: int, k: int) -> str:
        import math
        tokens = [str(i) for i in range(1, n+1)]
        res = ''
        k = k-1
        while n > 0:
            n -= 1
            a, k = divmod(k, math.factorial(n))
            res += tokens.pop(a)
        return res

func getPermutation(n int, k int) string {
    factorial := make([]int, n+1)
    factorial[0] = 1
    tokens := make([]int, n)
    for i := 1; i < n+1; i++ {
        factorial[i] = factorial[i-1]*i
        tokens[i-1] = i
    }
    
    k--
    var b strings.Builder
    for n > 0 {
        n--
        a := k / factorial[n] 
        k = k % factorial[n]
        fmt.Fprintf(&b, "%d", tokens[a])
        tokens = append(tokens[:a], tokens[a+1:]...)
    }
    return b.String()
}

上一篇 下一篇

猜你喜欢

热点阅读