难度:中等
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
题目分析:
这个题主要是题目的理解,啥叫下一个排列。以数组
1 2 7 4 3 1为例,观察一下发现右边1~7是升序的,下一个排列就是找到从右往左第一个破坏升序的数2,找到该位置,然后从该位置以后到结束的那一段数反转一下,让其反向升序,变成这样1 2 1 3 4 7。最后我们把2和右边第一个大于2的数进行交换,变成这样1 3 1 2 4 7。就完成了下一个排列。
C++ STL的库函数 next_permutation
用法:next_permutation(nums.begin(),nums.end());
参考代码:
#include "iostream"
#include "vector"
#include "string"
#include "unordered_map"
#include "deque"
using namespace std;
class Solution {
public:
void nextPermutation(vector<int>& nums) {
if (nums.empty())
return;
int pos = nums.size() - 1;
//先找出第一个从后往前破坏升序的数
while (pos > 0 && nums[pos] <= nums[pos - 1])
--pos;
//从第一个从后往前破坏升序的数的位置往后一位到数组最后一个位置进行逆序
reverse(nums.begin() + pos, nums.end());
--pos;//调整到第一个从后往前破坏升序的数的位置
if (pos >= 0)
{
//找到右边升序中第一个大于pos位置的数,进行交换
for (int i = pos+1; i < nums.size(); i++)
{
if (nums[pos] < nums[i])
{
swap(nums[pos],nums[i]);
break;
}
}
}
}
};
int main()
{
Solution solution;
vector<int> res = { 1,1,2 };
solution.nextPermutation(res);
for (int i = 0; i < res.size(); i++)
{
cout << res[i] << endl;
}
system("pause");
return 0;
}