Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place, do not allocate extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
大致意思:给定一个数组,按照字典序求下一个序列,如果已经是最后,则循环返回该组合的最小值
字典序:对于1,2,3,4...n的排列,不同的排列的先后关系是从左到右逐个比较对应的数字的先后来决定的,如同英文字典里的,单词的顺序是由单词的各个字符从左到右逐个比较决定的,例如n=4时,1234排在1243的前面
求根据字典序求下一个序列算法:
设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn
1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}
2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk (注意:此处pk应该从最右边开始找起,如果相等则优先靠右的值)
3)对换pj,pk
4)再将pj+1...pk-1pkpk+1pn倒转得到排列p'=p1p2....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。
example:
例如:14532是数字1~5的一个排列。从它生成下一个排列的步骤如下:
自右至左找出排列中第一个比右边数字小的数字4 14532
在该数字后的数字中找出比4大的数中最小的一个5 14532
将5与4交换 15432
将432倒转 15234
所以14532的下一个全排列为15432
/*
* next permutation
*
* @date 2015/8/9
*
*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void nextPermutation(vector<int>&num)
{
int len = num.size();
if(len <= 1)
return;
int j;
for(j = len-2;j >= 0;j--)
{
if(num[j]<num[j+1])
break;
}
if(j == -1)
{
reverse(num.begin(),num.end());
return;
}
int k = j+1;
for(int i = len-1;i>j;--i)
{
if(num[i]>num[j])
{
k = i;
break;
}
}
swap(num[j],num[k]);
reverse(num.begin()+j+1,num.end());
}
int main()
{
int num[] = {1,4,5,3,2};
vector<int> vec(num,num+5);
nextPermutation(vec);
return 0;
}
Note:关于nextPermutation函数的实现,类似于STL的排列算法,next_permutation函数
next_permutation(beg,end)
next_permutation(beg,end,comp)
这两个函数都是按照字典序进行排列的,将输入序列变换成下一个排列,即字典序的下一个排列,并返回true,如果输入序列为最后的序列,则循环到最开始的序列,返回false
在该数字后的数字中找出比4大的数中最小的一个5 14532
将5与4交换 15432
将432倒转 15234
所以14532的下一个全排列为15432
/*
* next permutation
*
* @date 2015/8/9
*
*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void nextPermutation(vector<int>&num)
{
int len = num.size();
if(len <= 1)
return;
int j;
for(j = len-2;j >= 0;j--)
{
if(num[j]<num[j+1])
break;
}
if(j == -1)
{
reverse(num.begin(),num.end());
return;
}
int k = j+1;
for(int i = len-1;i>j;--i)
{
if(num[i]>num[j])
{
k = i;
break;
}
}
swap(num[j],num[k]);
reverse(num.begin()+j+1,num.end());
}
int main()
{
int num[] = {1,4,5,3,2};
vector<int> vec(num,num+5);
nextPermutation(vec);
return 0;
}