60. 排列序列

60. 排列序列

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

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

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

给定 nk,返回第 k 个排列。

示例 1:

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

示例 2:

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

示例 3:

输入:n = 3, k = 1
输出:"123"

提示:

  • 1 <= n <= 9
  • 1 <= k <= n!

思路:
我的思路是需要第几个排列处理几次,那么怎么去寻找每次的下一次排列呢。

​ 自然是让靠后位的大的数和前面小的数交换例如:123 -》132

​ 但是交换要尽可能的小,就要去寻找合适的交换数,可以从后向前寻找一个非升序的数

​ 例如:123654 那么这里面从后向前找 3 就是非升序的数

​ 然后寻找比3大的数,但是这个数应该尽可能的小,那么就是4.

​ 注意,交换完后,应该将3后面的数全部排为升序,但是由于我们从后向前寻找的是非升序的,所以交换完自然是有序的,只需要倒转即可。如果难以理解,可以自行画图。

class Solution {
public:
    string getPermutation(int n, int k) {
        if(n==1)return "1";
        string temp="";
        //初始化
        for(int i=1;i<=n;i++){
            temp+=to_string(i);
        }
        for(int i=1;i<k;i++){
            //每次变换的操作
            permutation(temp);
        }
        return temp;
    }
    //找出当前排列的下一个排列
    void permutation(string& temp){
        int i=temp.size()-2;
        while(i>=0&&temp[i]>=temp[i+1]){
            i--;
        }
        if(i>=0){
            int j=temp.size()-1;
            while(j>=0&&temp[i]>=temp[j]){
                j--;
            }
            char t=temp[i];
            temp[i]=temp[j];
            temp[j]=t;
        }
        reverse(temp.begin()+i+1,temp.end());
    }

};
posted @ 2022-05-21 10:12  BailanZ  阅读(33)  评论(0编辑  收藏  举报