码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode_31题——Next Permutation(STL)

时间:2015-05-24 21:50:52      阅读:890      评论:0      收藏:0      [点我收藏+]

标签:

 

  下面摘抄的别人的讲解非常清楚

最近刷leetcode的时候遇见next permutation这道题,感觉挺有意思的一个题目,递归的方法是较简单并且容易想到的,在网上搜了其余的解法,就是std::next_permutation非递归解法,但是让人不是很舒服的就是关于原理的部分,千篇一律的都是摘抄《STL源码剖析》,也就是这样的。

在当前序列中,从尾端往前寻找两个相邻元素,前一个记为*i,后一个记为*ii,并且满足*i < *ii。然后再从尾端寻找另一个元素*j,如果满足*i < *j,即将第i个元素与第j个元素对调,并将第ii个元素之后(包括ii)的所有元素颠倒排序,即求出下一个序列了。

想必有点C++功底的人都能看明白源码是这么个意思,但是这能算是原理么,这至多算是实现吧。相比之下老外就严谨多了,我找到了一篇文章,防止丢失,我保存在这里。http://blog.csdn.net/qq575787460/article/details/41206601,其中图片资源已经没了。看了这篇文章之后,我豁然开朗,在佩服老外严谨的态度之余,也把自己的理解纪律下来,希望能够帮助到一些人。

 

首先,关于什么是全排列不做解释。如果一个排列为A,下一个排列为A_NEXT,那么A_NEXT一定与A有尽可能长的公共前缀。

看具体例子,一个排列为124653,如何找到它的下一个排列,因为下一个排列一定与124653有尽可能长的前缀,所以,脑洞大开一下,从后面往前看这个序列,如果后面的若干个数字有下一个排列,问题就得到了解决。

第一步:找最后面1个数字的下一个全排列。

124653,显然最后1个数字3不具有下一个全排列。

第二步:找最后面2个数字的下一个全排列。

124653,显然最后2个数字53不具有下一个全排列。

 

第三步:找最后面3个数字的下一个全排列。

124653,显然最后3个数字653不具有下一个全排列。

 

------插曲:到这里相信大家已经看出来,如果一个序列是递减的,那么它不具有下一个排列。

 

 

第四步:找最后面4个数字的下一个全排列。

124653,我们发现显然最后4个数字4653具有下一个全排列。因为它不是递减的,例如6453,5643这些排列都在4653的后面。

 

我们总结上面的操作,并总结出重复上面操作的两种终止情况:

1:从后向前比较相邻的两个元素,直到前一个元素小于后一个元素,停止

2:如果已经没有了前一个元素,则说明这个排列是递减的,所以这个排列是没有下一个排列的。

 

124653这个排列终止情况是上面介绍的第一种,从后向前比较相邻的2个元素,遇到4<6的情况停止。

并且我们可以知道:

1:124653和它的下一个排列的公共前缀为12(因为4653存在下一个排列,所以前面的数字12保持不变)

2:4后面的元素是递减的(上面介绍的终止条件是前一个元素小于后一个元素,这里是4<6)

 

现在,我们开始考虑如何找到4653的下个排列,首先明确4后面的几个数字中至少有一个大于4.

4肯定要和653这3个数字中大于4的数字中(6,5)的某一个进行交换。这里就是4要和6,5中的某一个交换,很明显要和5交换,如果找到这样的元素呢,因为我们知道4后面的元素是递减的,所以在653中从后面往前查找,找到第一个大于4的数字,这就是需要和4进行交换的数字。这里我们找到了5,交换之后得到的临时序列为5643.,交换后得到的643也是一个递减序列。

 

所以得到的4653的下一个临时序列为5643,但是既然前面数字变大了(4653--->5643),后面的自然要变为升序才行,变换5643得到5346.

所以124653的下一个序列为125643.

 

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

/*
void nextPermutation(vector<int>& nums)
{
	vector<int>::iterator i1,i2;
	i1=nums.end()-2;
	i2=nums.end()-1;
	int flag=0;
	while(1)
	{
		if(*i1<*i2)
		{
			for(vector<int>::iterator i=nums.end()-1;i>=i2;i--)
			{
				if(*i>*i1)
				{int temp;temp=*i;*i=*i1;*i1=temp;break;}
			}
			for(vector<int>::iterator ik1=i2,ik2=nums.end()-1;ik2>=ik1;ik1++,ik2--)
			{
				int temp;
				temp=*ik1;
				*ik1=*ik2;
				*ik2=temp;
			}
			flag=1;
			break;
		}

		if(i1==nums.begin())
			break;
		i1--;
		i2--;
	}
	if(flag==0)
	{
		for(vector<int>::iterator ik1=nums.begin(),ik2=nums.end()-1;ik2>=ik1;ik1++,ik2--)
		{
			int temp;
			temp=*ik1;
			*ik1=*ik2;
			*ik2=temp;
		}
		return;
	}
	if(flag==1)
		return;
}
*/


void nextPermutation(vector<int>& nums)
{
	int len_nums=nums.size();
	int i1=len_nums-2;
	int i2=len_nums-1;
	int flag=0;
	while(1)
	{
		if(nums[i1]<nums[i2])
		{
			for(int i=len_nums-1;i>=i2;i--)
				if(nums[i]>nums[i1])
				{int temp;temp=nums[i1];nums[i1]=nums[i];nums[i]=temp;break;}
				for(int ik1=i2,ik2=len_nums-1;ik1<=ik2;ik1++,ik2--)
				{int temp;temp=nums[ik1];nums[ik1]=nums[ik2];nums[ik2]=temp;}
				flag=1;
				break;
		}
		if(i1==0)
			break;
		i1--;
		i2--;
	}
	if(flag==0)
		for(int ik1=0,ik2=len_nums-1;ik1<=ik2;ik1++,ik2--)
		{int temp;temp=nums[ik1];nums[ik1]=nums[ik2];nums[ik2]=temp;}
		return;
}

/*
void FanZhuan(vector<int>& nums,int i,int j)
{
	if(i==j)
		return;
	int len=j-i+1;
	int n=j;
	for(int m=i;m<=len/2+i;m++)
	{
		int temp;
		temp=nums[m];
		nums[m]=nums[n];
		nums[n]=temp;
		n--;
	}
	return;
}

void nextPermutation(vector<int>& nums)
{
	int len_nums=nums.size();
	int i1=len_nums-2;
	int i2=len_nums-1;
	int flag=0;
	while(1)
	{
		if(nums[i1]<nums[i2])
		{
			for(int i=len_nums-1;i>=i2;i--)
				if(nums[i]>nums[i1])
				{int temp;temp=nums[i1];nums[i1]=nums[i];nums[i]=temp;break;}
				FanZhuan(nums,i2,len_nums-1);
				flag=1;
				break;
		}
		if(i1==0)
			break;
		i1--;
		i2--;
	}
	if(flag==0)
		FanZhuan(nums,0,len_nums-1);
		return;
}
*/
int main()
{
	vector<int> vec;
	vec.push_back(1);vec.push_back(2);
	nextPermutation(vec);

	for(int i=0;i<vec.size();i++)
		cout<<vec[i]<<endl;

}

  

leetcode_31题——Next Permutation(STL)

标签:

原文地址:http://www.cnblogs.com/yanliang12138/p/4526398.html

(1)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!