LeetCode31——————Next Permutation
这道题目就有意思了:
求一个序列的下一个全排列...........按照字典序。
当然看到这一题之后我的内心是崩溃的,因为以前真的没有接触过。。。。。(不像我在找关于全排列资料的时候有大神说高中信息竞赛都不屑于做。。。Orz)
好,什么是全排列?怎么实现全排列?我在网上看了一篇非常好多博文,分享:
http://segmentfault.com/a/1190000000666583
当然我们看这题,仔细读题后,才知道原来是按照字典序。
1.所谓字典序,比如说 123三个数字组成的全排列就有:
123 132 213 231 312 321
把123排在第一,是因为每一个元素都小于其后的元素,而132则是在固定1后所得到的新的组合。
同理可以分析出213 231 312 321 这样顺序的排列。
2.STL提供了template <class BidirectionalIterator>bool next_permutation(BidirectionalIterator first,BidirectionalIterator last)来实现基于less-than操作的字典序的求出来得序列的下一个全排列。
所以,你可以完全在LeetCode31中这样提交:
class Solution {
public:
void nextPermutation(vector<int>& nums) {
next_permutation(nums.begin(), nums.end());//STL
}
};
上述代码是完全没有问题可以通过的。
但是讲讲道理的话还是不太妥当。很惭愧,我自己并没有写出算法,而是参考了《STL源码剖析》关于next_permutation()部分的讲解才写出来。
代码如下:
class Solution {
private:
void Swap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
void Permutation(vector<int>&nums, int first, int last)
{
if (first == last)//长度为1
return;
int i;
i = last;
while (1)
{
int ii = i;
--i;
//锁定两个相邻的元素
if (nums[i] < nums[ii])//前一个元素小于后一个元素
{
int j = last;
while (!(nums[i] < nums[j--]));//尾端往前找找到比nums[i]大的元素
Swap(nums[i], nums[j+1]);
reverse(nums.begin()+ii, nums.end());
return ;
}
if (i == first)
{
reverse(nums.begin(),nums.end());
return ;
}
}
}
public:
void nextPermutation(vector<int>& nums) {
//next_permutation(nums.begin(), nums.end());//STL
int first = 0;
int last = nums.size()-1;
if (!nums.empty())
{
Permutation(nums, first, last);
}
else
{
return;
}
}
};