题目链接:https://leetcode-cn.com/problems/next-permutation
题目描述:
实现获取 下一个排列 的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)
必须 原地 修改,只允许使用额外常数空间。
示例 1:
输入:nums = [1,2,3]
输出:[1,3,2]
示例 2:
输入:nums = [3,2,1]
输出:[1,2,3]
示例 3:
输入:nums = [1,1,5]
输出:[1,5,1]
示例 4:
输入:nums = [1]
输出:[1]
提示:
1 <= nums.length <= 100
0 <= nums[i] <= 10
题解:
- 获取一个比当前排列更大的排列,只需将后面的大数与前面的数交换。比如 123456,将 5 和 6 交换就能得到一个更大的数 123465。
- 交换后获得的增幅要尽可能小。将一个 尽可能小的「大数」 与前面的「小数」交换。例如123465,下一个排列应该把 5 和 4 交换而不是把 6 和 4 交换。
- 将「大数」换到前面后,需要将「大数」后面的所有数重置为升序,升序排列就是最小的排列。
题解链接:下一个排列算法详解
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int i;
for(i = nums.size() - 2; i >= 0; i--) //从后往前遍历,找到第一个升序
{
if(nums[i] < nums[i + 1])
break;
}
if(i == -1) //不存在下一个更大的排列
reverse(nums.begin(), nums.end());
else{
for(int j = nums.size() - 1; j >= i+1; j--) //查找后续序列中比nums[i]大的最小值
{
if(nums[i] < nums[j])
{
swap(nums[i], nums[j]); //将大数与小数交换
reverse(nums.begin() + i + 1, nums.end()); //将「大数」后面的所有数重置为升序
break;
}
}
}
}
};