31. 下一个排列-中等-数组
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
题解
此题有点不太说人话,此处附上一个评论,一看就懂:
题干的意思是:找出这个数组排序出的所有数中,刚好比当前数大的那个数
比如当前 nums = [1,2,3]。这个数是123,找出1,2,3这3个数字排序可能的所有数,排序后,比123大的那个数 也就是132
如果当前 nums = [3,2,1]。这就是1,2,3所有排序中最大的那个数,那么就返回1,2,3排序后所有数中最小的那个,也就是1,2,3 -> [1,2,3]
故,不算reverse
需要两次从大到小的遍历,第一次遍历找到逆序的值,第二次遍历,找到刚好比第一次找的值大的值。
之后在指针标记的位置到最后reverse
一遍。
class Solution {
public void nextPermutation(int[] nums) {
boolean flag = true; // 如果数组是降序的,那么我们需要把它reverse一下
int N = nums.length;
int p = 0; // 用于存储交换位置的指针
// 第一次遍历,找到需要交换的数字
for(int i=N-1; i>0; i--){
if(nums[i] > nums[i-1]){
p = i;
flag = false;
break;
}
}
if(flag){
for(int i=0; i < N/2 ;i++){
swap(nums, i, N-i-1);
}
}else{
// 第二次遍历,查找刚好大于nums[p-1]的值
for(int i=N-1; i>0; i--){
if(nums[i] > nums[p-1]){
swap(nums, i, p-1);
break;
}
}
// 将p之后全部reverse一遍
for(int i=p; i < (N+p)/2 ;i++){
swap(nums, i, N+p-i-1);
}
}
}
public void swap(int[] nums, int i, int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}