zoukankan      html  css  js  c++  java
  • Leetcode 60.第k个排列

    第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]。
    • 给定 的范围是[1,  n!]。

    示例 1:

    输入: n = 3, k = 3

    输出: "213"

    示例 2:

    输入: n = 4, k = 9

    输出: "2314"

    提示:

    这道题我一上来使用了backtracking的方法依次构造出排列数,当然结果不出所料的TLE了。实际上,仔细观察这些数字,我们还是不难发现一些规律的。

    假设有四位数字{1, 2, 3, 4},那么他们能够产生的排列数是什么呢?

    • 1 + {2, 3, 4}
    • 2 + {1, 3, 4}
    • 3 + {1, 2, 4}
    • 4 + {1, 2, 3}

    其实就是选定第一位数字后,其他剩下的数字进行排列组合,就能求出以该数字打头的所有排列组合。想必已经能发现一些规律了,我们干脆再举一个具体的例子,比如我们现在想要找第14个数,那么由于14 = 6 + 6 + 2。因此第一个数打头的是3,然后再求{1, 2, 4}中第二个排列组合数,答案是"142"。所以最终答案就是"3142"啦。

    这里有一些问题是需要我们注意的:

    • 构造排列数从最高位开始,当选出一个数字后,就应当把这个数字erase掉,防止后面又出现;
    • 我们所要求的第k个数需要在每次循环中减去对应的值;
    • 注意程序中的数组是从0开始的,但题目的输入是从1开始计数的。
     1 class Solution{
     2 public:
     3     string getPermutation(int n,int k){
     4         vector<int> permutation(n+1,1);
     5         for(int i=1;i<=n;i++){
     6             permutation[i]=permutation[i-1]*i;
     7         }
     8         vector<char> digits={'1','2','3','4','5','6','7','8','9'};
     9         int num=n-1;
    10         string res;
    11         while(num){
    12             int t=(k-1)/(permutation[num--]);
    13             k=k-t*permutation[num+1];
    14             res.push_back(digits[t]);
    15             digits.erase(digits.begin()+t);
    16         }
    17         res.push_back(digits[k-1]);
    18         return res;
    19     }
    20 };
  • 相关阅读:
    vb.net与XML之间的操作
    C#动态生成WORD文档并进行操作。
    Excel的VBA连接数据库方法
    C#动态生成EXCLE并进行添加内容
    c#与WORD之间的基本操作
    C#运用ADO.net动态创建excle并进行相应的数据修改显示
    USACOMother's Milk
    USACOArithmetic Progressions
    USACONumber Triangles
    USACOMilking Cows
  • 原文地址:https://www.cnblogs.com/kexinxin/p/10163042.html
Copyright © 2011-2022 走看看