美文网首页算法提高之LeetCode刷题C++
60.Permutation Sequence-Leetcode

60.Permutation Sequence-Leetcode

作者: analanxingde | 来源:发表于2018-01-15 16:16 被阅读2次

    基础回顾

    String

    头文件中必须包括<string>

    string的声明初始化

        string s1 = "abcdefg";  //初始化方式1  
        string s2("abcdefg");   //初始化方式2  
        string s3 = s2;         //通过拷贝构造函数 初始化s3  
        string s4(7,'s');       //初始化7个s的字符串  
    

    遍历

    1.str[i]
    2.迭代器: 
        for(string::iterator it = s1.begin(); it!= s1.end(); it++)  
        {  
            cout << *it << " ";  
        }
    3.str.at[i]//此方式可以在越界时抛出异常
    

    string与char*

    //字符指针和字符串的转换  
    void strConvert()  
    {  
        cout << "字符指针和字符串的转换:"  <<endl;  
        string s1 = "abcdefg";  //初始化字符串  
      
        cout << "string转换为char*:"  <<endl;  
        //string转换为char*  
        cout << s1.c_str() <<endl;  //s1.c_str()即为s1的char *形式  
      
        cout << "char*获取string内容:"  <<endl;  
        //char*获取string内容  
        char buf[64] = {0};  
        s1.copy(buf, 7);//复制7个元素  
        cout << buf <<endl;  
    } 
    

    字符串连接

    s1.append(s2);
    s1+=s2;
    

    string与int转化(注意stringstream)

    //int与char*
    char* n=a+'0'
    itoa(num, str, 10); //stdlib.h中的函数
    //int to string,其余类型之间转换也可参考类似的方法stringstream可以stringstream可以吞下任何类型,根据实际需要吐出不同的类型。
    stringstream stream;//<sstream>
    stream<<n;
    stream.str();//stream>>str;
    //string to int
    n = atoi(str.c_str())
    

    我的算法(受nextPermutation影响大,算法效率低)

    nextPermutation算法思想:

    https://www.nayuki.io/page/next-lexicographical-permutation-algorithm

    #右数第一个非降序序列的前一个元素下标pivot
    #右数第一个大于s[pivot]的值的下标设为successor
    #交换successor与pivot对应的元素
    #将pivot右边的所有元素逆序
    
    class Solution {
        //初始化s,后根据k进行循环限制,每次都取下一个排列数(根据NextPermutation的算法):效率很低
    public:
        string getPermutation(int n, int k) {
            int i,j=0;
            for(i=1;i<=n;i++)
            {
                j=j*10+i;
            }
            n=j;
            stringstream ss;
            string begin;
            ss<<n;
            begin=ss.str();
            if(n==1 ||k==1)
            {
                return begin;
            }
            
            for(i=2;i<=k;i++)
            {
                begin=NextPermutation(begin);
            }
            
            return begin;
        }
         string NextPermutation(string s){
             int len=s.length();
             int i=len-1;
             while(s[i]<=s[i-1] && i-1>=0)
             {
                 i-=1;
             }
             int pivot=i-1;     #右数第一个非降序序列的前一个元素下标pivot
             int successor;
             for(i=len-1;i>pivot;i--)
             {
                 if(s[i]>s[pivot])
                 {
                     successor=i;
                     break;    #右数第一个大于s[pivot]的值的下标
                 }
             }
             char middle=s[successor];
             s[successor]=s[pivot];
             s[pivot]=middle;  #交换successor与pivot对应的元素
             int j;
             for (i=pivot+1,j=len-1;i<j;i++,j--)
             {                        #将pivot右边的所有元素逆序
                middle=s[i];
                s[i]=s[j];
                s[j]=middle;
             }
    
            return s;
         }
    };
    

    最优解法

    http://blog.csdn.net/cinderella_niu/article/details/42927119
    主要思想是按阶乘表示可能的组合种类:
    1,2,3,… , n构建的全排列中,返回第k个排列。
    题目告诉我们:对于n个数可以有n!种排列;那么n-1个数就有(n-1)!种排列。
    那么对于n位数来说,如果除去最高位不看,后面的n-1位就有 (n-1)!种排列。
    所以,还是对于n位数来说,每一个不同的最高位数,后面可以拼接(n-1)!种排列。
    所以你就可以看成是按照每组(n-1)!个这样分组。
    利用 k/(n-1)! 可以取得最高位在数列中的index。这样第k个排列的最高位就能从数列中的index位取得,此时还要把这个数从数列中删除。
    然后,新的k就可以有k%(n-1)!获得。循环n次即可。

    class Solution {
    public:
        string getPermutation(int n, int k) {
            string ret;
            vector<int> factorial(n,1);     #计算阶乘
            vector<char> num(n,1);
            
            for(int i=1; i<n; i++) 
                factorial[i] = factorial[i-1]*i;
            
            for(int i=0; i<n; i++)
                num[i] = (i+1)+'0';
            
            k--;
            for(int i=n; i>=1; i--) {
                int j = k/factorial[i-1];
                k %= factorial[i-1];
                ret.push_back(num[j]);
                num.erase(num.begin()+j); //删除第j个元素,同时调整元素排序关系
            }
            
            return ret;
        }
    };
    

    相关文章

      网友评论

        本文标题:60.Permutation Sequence-Leetcode

        本文链接:https://www.haomeiwen.com/subject/dxrroxtx.html