题目:
实现下一个排列,它将数字重新排列成字典下一个更大的数字排列。
如果这种安排不可能,则必须将其重新排列为尽可能低的顺序(即按升序排序)。
更换必须就地,并且只使用恒定的额外内存。
这里有些例子。 输入位于左侧列中,其相应的输出位于右侧列中。
示例:
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
思路:
(1)从后向前遍历,找到第一个不满足降序的元素;若初始序列全部是降序,则i为-1,直接跳转至(3);
(2)将该元素同它后面的元素中比它大的第一个元素交换;
(3)将该元素后的所有元素排列,使之成为最小的排列。
C++代码实现(使用了一个快速排序)
class Solution {
public:
void quicksort(vector<int>& nums,int begin,int end)
{
if(begin >= end)
return;
int i = begin;
int j = end;
int key = nums[begin];
while(i != j)
{
while(nums[j] >= key && i<j)
{
j--;
}
while(nums[i] <= key && i<j)
{
i++;
}
if(i < j)
{
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
nums[begin] = nums[i];
nums[i] = key;
quicksort(nums,begin,i-1);
quicksort(nums,i+1,end);
}
void swap(vector<int> &nums,int i,int j)
{
int tem = nums[i];
nums[i] = nums[j];
nums[j] = tem;
}
void nextPermutation(vector<int>& nums) {
if(nums.size() <= 1)
return;
int i = nums.size()-2;
while(nums[i] >= nums[i+1] && i>=0) ///注意会出现大于等于的情况[0,1,1,0,4,4]
{
i--;
}
cout<<i<<endl;
if(i >= 0)
{
int min = 9999;
int k;
for(int j = i+1;j<nums.size();j++)
{
if(min > nums[j] && nums[j] > nums[i])
{
min = nums[j];
k = j;
}
}
swap(nums,i,k);
}
int e = nums.size()-1;
i++;
quicksort(nums,i,e);
}
};