Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place, do not allocate extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
求下一个全排列。
首先全排列是一种升序到降序的排列,例如给出123,那么第一个一定是升序123,最后一个一定降序321,三个不含有重复元素的全排列有A33=6个,含有重复元素的全排列个数会减少,例如[1,1,5] ,[1,5,1],[5,1,1] 。
给出4个不重复元素的全排列以观察规律:
1234
1243
1324
1342
1423
1432
2134
2143
2314
2341
2413
2431
3124
3142
3214
3241
3412
3421
4123
4132
4213
4231
4312
4321
思路:找出【尽量靠前的】位置,这个位置满足下面的条件:
从这个位置的下一个位置开始,一直到末尾的所有元素一起构成一个降序序列。
以“3142”为例子,找到的位置是index=1,元素是1,说明1需要更换,然后寻找index=2开始到末尾的最小的【比num[1]大的】元素,把这个找到的最小元素交换到index=1的位置,再把index=2开始的元素排序,变换过程也就是"3142"->"3241"->"3214"。
再看“3421”,找到尽量靠前的位置使得这个位置之后的元素形成降序序列,找到index=0的位置,找到比3大的最小元素4,
交换形成"4321",排序index=1开始的位置,形成"4123"
另外降序的下一个全排列是升序,这是一个环。
public static void nextPermutation(int[] nums)
{
int len=nums.length;
int i=0;
for(;i<len;i++)
{
boolean descend=true;
for(int j=i+1;j<len-1;j++)
if(nums[j+1]>nums[j])
{
descend=false;
break;
}
if(descend)
break;
}
int min=Integer.MAX_VALUE;
int minindex=-1;
int k=i+1;
for(;k<len;k++)
{
if(nums[k]>nums[i]&&nums[k]<min)
{
min=nums[k];
minindex=k;
}
}
if(minindex==-1)
{
for(int f=0,g=len-1;f<len/2;f++,g--)
{
int temp=nums[f];
nums[f]=nums[g];
nums[g]=temp;
}
return ;
}
nums[minindex]=nums[i];
nums[i]=min;
Arrays.sort(nums, i+1, len);
}