【Permutation Sequence】cpp

题目

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 (ie, 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: Given n will be between 1 and 9 inclusive.

代码

复制代码
class Solution {
public:
    string getPermutation(int n, int k)
    {
        std::stringstream result;
        // if the digit has been used
        int flag[10];
        for(int i = 1; i<10; ++i) flag[i]=1;
        // calculate each digit
        int factorical,quotient,remaind=k-1;
        for (int i = 1; i<=n; ++i)
        {
             factorical = Solution::getFactorical(n-i);
            quotient = remaind/factorical;
            int tmp = 0;
            for(int j=1; j<=9; ++j){
                tmp = tmp + flag[j];
                if ( tmp==(quotient+1) ){
                    quotient = j;
                    break;
                }
            }
            result << quotient;
            flag[quotient] = 0;
            remaind = remaind%factorical; // update remaind
        }
        return result.str();
    }
    static int getFactorical(int n){
        int result = 1;
        for (int i = 1; i <= n; ++i){
            result = result * i;
        }
        return result;
    }
};
复制代码

Tips:

1. 主要思路是康托编码,具体什么是康托编码(http://blog.sina.com.cn/s/blog_4bf7b6580100l2zs.html

2. 把计算阶乘的代码单独列出来

3. 对于c++如何将int转为字符不太懂,因此用了sstream的这个方法,后面遇到其他的方法再改进一下。

======================================================

第二次过这道题,对康托编码的算法有些生疏了,参考了blog才回忆起来。然后扫了一些细节,形成了自己的代码。

复制代码
class Solution {
public:
        string getPermutation(int n, int k)
        {
            vector<char> ret;
            vector<bool> visit(9,false);
            k = k-1;
            for ( int i=n-1; i>=0; --i)
            {
                int factor = Solution::factorial(i);
                int num_less = k / factor;
                // find num less
                int j=0;
                int count = 0;
                for ( ; j<9; ++j )
                {
                    if ( !visit[j] )
                    {
                        if ( count==num_less ) break;
                        count++;
                    }
                }
                visit[j] = true;
                ret.push_back(j+'1');
                k = k % factor; 
            }
            return string(ret.begin(),ret.end());
        }
        static int factorial(int n)
        {
            if ( n==0 || n==1 ) return 1;
            int ret = 1;
            for ( int i = 1; i<=n; ++i) ret = ret * i;
            return ret;
        }
};
复制代码

 

posted on   承续缘  阅读(216)  评论(0编辑  收藏  举报

编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示