Leetcode60.Permutation_Sequence

数学基础:康托展开
对于具有n个元素的集合,以’1’开头的数字序号范围是[1,(n-1)!],以’2’开头的数字序号范围是[(n-1)!,2(n-1)!]…以此类推。
所以寻找n个数中的第k个排列,就可以运用上述方法:确定n个数中第一个数,再去掉该数,运用同样方式确定(n-1)个数中的第一个数。
例:求 n=5 , k = 17
k = 17,前边有16个排列,即寻找前面有16个排列的排列。
{1,2,3,4,5}
16 ÷ 4!= 0 … 16 五位数中第一位的序号范围在[1,4!],所以第一位是’1’。
{2,3,4,5}
16 ÷ 3!= 2 … 4 五位数中第二位的序号范围在[23!+1,33!],所以第二位是’4’。
{2,3,5}
4 ÷ 2!= 2 … 0 五位数中第三位的序号范围在[22!+1,32!],所以第三位是’5’
{2,3}
0 ÷ 1!= 0 … 0 第四位是’2’
{3}
0 ÷ 0!= 0 … 0 第五位是‘3’
所以n = 5,k = 17 的数为"14523"
时间复杂度:O(k*n)(阶乘时间复杂度为n,执行k次)
C++代码:

class Solution{
	int factorial(int n)
	{
		int result = 1;
		for (int i = 1; i <= n; i++)
			result *= i;
		return result;
	}
public:
	string getPermutation(int n, int k) {
		vector<int> num_set;
		for (int i = 1; i < n + 1; i++)
			num_set.push_back(i);
		string result;
		k--;
		for (int i = n - 1; i > 0; i--)
		{
			int permute = k / factorial(i);
			k %= factorial(i);
			result.push_back(num_set[permute] + '0');
			num_set.erase(num_set.begin() + permute);
		}
		result.push_back(num_set[0] + '0');
		return result;
	}
};

猜你喜欢

转载自blog.csdn.net/qq_42263831/article/details/82850429