LeetCode刷题-第k个排序

第k个排序

题目描述

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

按大小顺序列出所有排列情况,并一一标记,当 n = 3 时, 所有排列如下:
“123”
“132”
“213”
“231”
“312”
“321”
给定 n 和 k,返回第 k 个排列。

说明:
给定 n 的范围是 [1, 9]。
给定 k 的范围是[1, n!]。

样例

  1. 输入: n = 3, k = 3
    输出: “213”
  2. 输入: n = 4, k = 9
    输出: “2314”

Code1

使用next_permutation();

string getPermutation(int n, int k) {
	string s(n, '0');
	for(int i=0; i<n; ++i) {
		s[i]+=i+1;
	}
	for(int i=0; i<k-1; ++i) {
		next_permutation(s.begin(), s.end());
	}
	return s;
}

template<typename BidiIt>
bool next_permutation(BidiIt first, BidiIt last) {
	const auto rfirst = reverse_iterator<BidiIt>(last);
	const auto rlast = reverse_iterator<BidiIt>(first);

	auto pivot=next(rfirst);

	while(pivot !=rlast && *pivot >= *prev(pivot)) {
		++pivot;
	}

	if(pivot ==rlast) {
		reverse(rfirst, rlast);
		return false;
	}

	auto change=find_if(rfirst, pivot, bind1st(less<int>(), *pivot));

	swap(*change, *pivot);
	reverse(rfirst, pivot);

	return true;
}

Code2

康托编码,时间复杂度O(n),空间复杂度O(1);

string getPermutation(int n, int k) {
	string s(n, '0');
	for(int i=0; i<n; ++i) {
		s[i]+=i+1;
	}
	return kth_permutation(s, k);
}

private:
int factorial(int n) {
	int result=1;
	for(int i=1; i<=n; ++i) {
		result*=i;
	}
	return result;
}
template<typename Sequence>
Sequence kth_permutation(const Sequence &seq, int k) {
	const int n=seq.size();
	Sequence S(seq);
	Sequence result;
	int base=factorial(n-1);
	--k;
	for(int i=n-1; i>0; k%=base,base/=i,--i) {
		auto a=next(S.begin(), k/base);
		result.push_back(*a);
		S.erase(a);
	}
	result.push_back(S[0]);
	return result;
}

若有疑问可评论交流=_=!

猜你喜欢

转载自blog.csdn.net/baidu_34884208/article/details/88387574