题目:
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
思路:首先考虑一种特殊情况,什么逆序递增序列不存在更大序列例如[4,3,1],
如递增序列前面存在一个比当前最大值小的数字例如[2,4,3,1]时,比他
大的序列中最小的就需要将他和他后面序列中的数字交换但是又不能取比
他小或者相等的,那样的话序列更加小或者不变了,所以只能取比他大中最小的,
交换之后最高位变大了,但是序列仍然不是比原序列大的所有序列中最小的,因为
最高为变大时,无论地位顺序如何,序列都会增大,所以我们将低位序列变成最小的升序序列后
还是比原序列大.这也是最后的结果
//思想:找到下一个排列:从后往前双重遍历,找到一个比当前数字大的若没找到返回该序列的升序排列序列
class Solution {
public void nextPermutation(int[] nums) {
if(nums == null || nums.length == 0)
return ;
int left = 0;
int right = nums.length-1;
for(;right >0 ; right --){
//找出第一个逆序递减序列下标
int preIndex = right-1;
if(nums[right]>nums[preIndex]){
//查找插入位置使right后面的子序列依然保持顺序
int swapIndex=right+1;
for( ;swapIndex < nums.length ; swapIndex++){
if(nums[swapIndex] <= nums[preIndex])
break;
}
swap(nums,preIndex,swapIndex-1);
break;
}
}
reverse(nums,right,nums.length-1);
}
public void swap(int[] nums , int i , int j){
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public void reverse(int[] nums,int left,int right){
while(left <right){
swap(nums,left,right);
left ++;
right --;
}
}
}