Question:
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
本题难度medium。
算法1:
【复杂度】
时间O(N) 空间O(1)
【思路】
从后往前搜索第一个升序对。比如:1452321,最右边的升序对就是23。为什么是最右边这个?因为题目要求是“next greater”,所以尽量动低位。我将可能的情况列举出来:
一直升序:1 23->1 32
一直降序:3 21->1 23
先降后升:321 45->321 54
没变化:1111->不处理
以上的情况处理都很简单,我将要处理的部分都用空格区分开来了。可以看到,仅仅是将最右边的升序对进行swap(或整体升序处理)即可。最麻烦的情况就是:
先升后降:2 13 21
如果 1 与 3 swap,得到 2 31 21却不是next greater。
正确的办法是将 3 21进行升序排列,选一个刚好比1大的数与 1 swap即可,得到 2 21 13
【附】
将各种case考虑清楚即可解题。
【代码】
public class Solution {
public void nextPermutation(int[] nums) {
//require
if(nums==null)
return;
int size=nums.length;
if(size<2)
return;
int up_p=-1; //save the ascending pair index
//invariant
for(int i=size-1;i>0;i--){
if(nums[i-1]<nums[i]){
up_p=i-1;
break;
}
}
if(up_p==-1)
Arrays.sort(nums);
else{
if(up_p+1==size-1){
//swap
int temp=nums[up_p];
nums[up_p]=nums[up_p+1];
nums[up_p+1]=temp;
}else{
//sort
Arrays.sort(nums,up_p+1,size);
for(int i=up_p+1;i<size;i++)
if(nums[i]>nums[up_p]){
//swap
int temp=nums[up_p];
nums[up_p]=nums[i];
nums[i]=temp;
return;
}
}
}
}
}
【follow up】
应该有更快的算法,先留白待续。