Permutation Sequence 第k个排列

给出集合 [1,2,3,…,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"

思路:这道题的第一想法就是在之前那道题的基础上添加一个计数器Permutation,如果当前计数器等于k那么返回,但是发现我真是simple,之前的通过固定某一个数,然后全排列后面的所有数的方法出来的并不是顺序的。所以要换种方法。

参考这篇帖子:https://www.cnblogs.com/grandyang/p/4358678.html

这道题的解法是找规律,以输入[1,2,3,4]为例:

所有情况按照顺序是:

1234
1243
1324
1342
1423
1432
2134
2143
2314 
2341
2413
2431
3124
3142
3214
3241
3412 <--- k = 17
3421
4123
4132
4213
4231
4312
4321

第一个数有6种情况(3!),如果固定了第一个数,第二个数有2种情况(2!),如果固定了第一二个数,第三个数有1种情况(1!),固定了前3个,第四个数有1种情况(0!)。那么怎么第几位数应该是多少呢?以n=4,k=17来举例子:

k=17相当于下标16(以后都是以下标0开始算),由于第0位数有6种情况,所以16/6=2,所以第0位数是1,2,3,4的第2位即3,那么剩下16%6=4位,第1位数有2种情况,所以4/2=2,所以第1位数是1,2,4中的4,这时剩下4%2=0,第2位0/1=0,所以第2位是1,2中的1,剩下0%1=0,第3位0/1=0,所以第3位是剩下的2的2,所以最后的数字是3,4,1,2

所以规律是:

a0=k/(n-1)!

k=k%(n-1)!

a1=k/(n-2)!

k=k%(n-2)!

......

参考代码:

class Solution {
public:
    string getPermutation(int n, int k) {
	string res;
	vector<int> f(n, 1);
	for (int i = 1; i < n; i++) f[i] = f[i - 1] * i;
	k--;
	string num = "123456789";
	for (int i = n; i >= 1; i--) {
		int j = k / f[i - 1];
		k %= f[i - 1];
		res.push_back(num[j]);
		num.erase(j, 1);
	}
	return res;        
    }
};

猜你喜欢

转载自blog.csdn.net/qq_26410101/article/details/81261401