思路:从后往前找第一个升序对,将pre指针指向升序对的第一个元素,然后从后往前找第一个大于pre指向的数的数字,然后交换该数字和pre指向的数字。然后将pre后面的数字逆过来
比如 1 2 3 4 0的下一个全排列。从后往前找第一个升序对是(3, 4),从后往前找到第一个大于3的数字是4,即找第一个大于” 前面找到的升序对的第一个元素3 ”的数字。 然后交换3和4得到12430,然后再把升序对后面的数字逆过来,得到12403.即12403就是12340的下一个排列。
class Solution {
public:
void nextPermutation(vector<int> &num) {
int n = num.size();
if(n <= 0)
return ;
if(n == 1)//只有一个数字
return ;
int pre = n - 2, net = n - 1;//分别升序对的位置
while(pre >= 0 && num[pre] >= num[net])//从后往前找第一个升序对
{
pre--;
net--;
}
if(pre >= 0)//找到升序对
{
//从后往前找第一个大于pre的数字并交换
for(int i = n -1; i != pre; i--)
{
if(num[i] > num[pre])
{
swap(num[i], num[pre]);
break;
}
}
reverse(num, pre + 1, n - 1);//把pre后的数字顺序颠倒过来
}
else
{
//从后往前没有找到第一个升序对,说明该数字是最大了。
//所以没有下一个全排列,按题意直接把数组翻转。
reverse(num, 0, n - 1);
}
return ;
}
void reverse(vector<int> & num, int start, int end)
{
//vector<int>temp;
int * temp = new int[end - start + 1];
int p = 0;
for(int i = end; i >= start; i--)
temp[p++] = num[i];
int j = 0;
for(int i = start; i <= end; i++)
num[i] = temp[j++];
delete []temp;
}
};