实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
完整代码
这道题大概知道如何求结果,自己手算可以算的出来,但是不知道代码实现是什么思想,参考讨论区的思想如下。
基本思想:
- 从右往左遍历数组,找到第一个正序的数,下标为 i(后一个大于前一个的数),例如:[3,4,5,2,1],找到5
- 将该数一直到结尾的数逆序,[3,4,1,2,5]
- 将第 i-1 个数和 i 后面的比第 i-1 个数大的最小的数 交换 [3,5,1,2,4]
class Solution {
public:
void nextPermutation(vector<int>& nums) {
if(nums.size()<2)
return;
int len=nums.size();
//1.从右往左找到第一个后一个比前一个大的数
int i=len-1;
while(i>0&&nums[i]<=nums[i-1])
--i;
//2.将第i个数一直到结尾的数逆序
reverse(nums.begin()+i,nums.end());
//3.交换第i-1个数和i之后中比第i-1个数大的数中的最小数,不一定是结尾位置的数,因为其后的数都是递增排序的,所以从前往后遍历,第一个找到的就是
if(i>0){//如果i==0就不用交换了
for(int k=i;k<len;++k){
if(nums[k]>nums[i-1]){
int temp=nums[k];
nums[k]=nums[i-1];
nums[i-1]=temp;
break;
}
}
}
}
};
执行结果:通过
显示详情
执行用时 :12 ms, 在所有 C++ 提交中击败了60.65%的用户
内存消耗 :8.4 MB, 在所有 C++ 提交中击败了95.94%的用户
做完这道题,我觉得看到一个问题,只要是有了清晰的思路,只需将思路用代码体现出来就OK。