Next Permutation
2015-12-26 13:45
309 查看
原题地址:https://leetcode.com/submissions/detail/48922153/
所谓一个排列的下一个排列的意思就是这一个排列与下一个排列之间没有其他的排列。这就要求这一个排列与下一个排列有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上。这句话的意思我一直没弄明白!
对于数字序列:
先看前面2排的话,可以看出来第二排是比第一排要大的,参考字符串比较大小的问题。那么第2个排列是不是第一个排列的下一个排列呢。很明显不是,第3个排列才是,那么如何获取到下一个排列呢。步骤比较简单:假设数组大小为n
1.从后往前,找到第一个A[i-1]<A[i]的。也就是第一个排列中的6那个位置,可以看到A[i]到A[n-1]这些都是单调递减序列。
2.从A[n-1]到A[i]中找到一个比A[i-1]大的值(也就是说在A[n-1]到A[i]的值中找到比A[i-1]大的集合中的最小的一个值)
3.交换这两个值,并且把A[n-1]到A[i]排序,从小到大。
Well,infacttheproblemofnextpermutationhasbeenstudiedlongago.FromtheWikipediapage,inthe14thcentury,amannamedNarayanaPanditagivesthefollowingclassicandyetquitesimplealgorithm(withminormodificationsinnotationstofittheproblemstatement):
Findthelargestindex
Findthelargestindex
Swapthevalueof
Reversethesequencefrom
Quitesimple,yeah?Nowcomesthefollowingcode,whichisbarelyatranslation.这就是上面图片的另外一种表述!!
就看第一个算法就好了:
所谓一个排列的下一个排列的意思就是这一个排列与下一个排列之间没有其他的排列。这就要求这一个排列与下一个排列有尽可能长的共同前缀,也即变化限制在尽可能短的后缀上。这句话的意思我一直没弄明白!
对于数字序列:
先看前面2排的话,可以看出来第二排是比第一排要大的,参考字符串比较大小的问题。那么第2个排列是不是第一个排列的下一个排列呢。很明显不是,第3个排列才是,那么如何获取到下一个排列呢。步骤比较简单:假设数组大小为n
1.从后往前,找到第一个A[i-1]<A[i]的。也就是第一个排列中的6那个位置,可以看到A[i]到A[n-1]这些都是单调递减序列。
2.从A[n-1]到A[i]中找到一个比A[i-1]大的值(也就是说在A[n-1]到A[i]的值中找到比A[i-1]大的集合中的最小的一个值)
3.交换这两个值,并且把A[n-1]到A[i]排序,从小到大。
Well,infacttheproblemofnextpermutationhasbeenstudiedlongago.Fromthe
Findthelargestindex
ksuchthat
nums[k]<nums[k+1].Ifnosuchindexexists,thepermutationissortedindescendingorder,justreverseittoascendingorderandwearedone.Forexample,thenextpermutationof
[3,2,1]is
[1,2,3].
Findthelargestindex
lgreaterthan
ksuchthat
nums[k]<nums[l].
Swapthevalueof
nums[k]withthatof
nums[l].
Reversethesequencefrom
nums[k+1]uptoandincludingthefinalelement
nums[nums.size()-1].
Quitesimple,yeah?Nowcomesthefollowingcode,whichisbarelyatranslation.这就是上面图片的另外一种表述!!
就看第一个算法就好了:
classSolution{ public: voidnextPermutation(vector<int>&nums)//注意,这里传进来的可是引用 { intindex1,index2; for(inti=nums.size()-1;i>=0;i--) { if(i>=1&&nums[i-1]<nums[i]) { index1=i-1; break; } if(i==0) { reverse(nums,0,nums.size()-1); return; } } for(intj=nums.size()-1;j>=0;j--) { if(nums[j]>nums[index1]) { index2=j; break; } } inttemp=nums[index1]; nums[index1]=nums[index2]; nums[index2]=temp; reverse(nums,index1+1,nums.size()-1); } voidreverse(vector<int>&nums,intbegin,intend) { while(begin<end) { inttemp=nums[begin]; nums[begin]=nums[end]; nums[end]=temp; begin++; end--; } } };
#include<iostream>
#include<string>
#include<vector>
usingnamespacestd;
classSolution{
public:
voidnextPermutation(vector<int>&nums)
{
intindex1,index2;
for(inti=nums.size()-1;i>=0;i--)
{
if(i>=1&&nums[i-1]<nums[i])
{
index1=i-1;
break;
}
if(i==0)
{
reverse(nums,0,nums.size()-1);
return;
}
}
for(intj=nums.size()-1;j>=0;j--)
{
if(nums[j]>nums[index1])
{
index2=j;
break;
}
}
inttemp=nums[index1];
nums[index1]=nums[index2];
nums[index2]=temp;
reverse(nums,index1+1,nums.size()-1);
}
voidreverse(vector<int>&nums,intbegin,intend)
{
while(begin<end)
{
inttemp=nums[begin];
nums[begin]=nums[end];
nums[end]=temp;
begin++;
end--;
}
}
};
intmain()
{
Solutiontest;
vector<int>arr;
arr.push_back(1);
arr.push_back(3);
arr.push_back(2);
for(inti=0;i<arr.size();i++)
cout<<arr[i]<<endl;
cout<<"after:"<<endl;
test.nextPermutation(arr);
for(inti=0;i<arr.size();i++)
cout<<arr[i]<<endl;
}
相关文章推荐
- GOROOT、GOPATH、GOBIN、project目录
- Fragment
- 四层和七层负载均衡的区别
- Android获取TextView控件高度(其它View类似,TextView有特殊之处)
- 最后关于Pipeline完整的图如下:
- 操作系统实验之作业调度算法
- python的out of memory问题
- nginx 配置详解
- Java 多线程(1)-Thread和Runnable
- codeforces 508D . Tanya and Password 欧拉通路
- HDU 1003:Max Sum【水】
- <php+mysql>PHP脚本对数据库的基本操作,查找,删除,循环输出
- VS project 根目录 配置OpenGL 相关库
- 微信分享失败之checkArgs fail, thumbData is invalid
- 【剑指offer】2.4.1查找和排序——面试题8:旋转数组的最小数字
- 与机器学习祖师爷 杰夫.辛顿 的交流
- OSGI blueprint Converter的使用
- 在 vSphere Web Client 中恢复孤立的虚拟机
- oc内存管理
- 既然流量劫持那么讨厌 那么大型互联网公司怎么解决