问题
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
。
例子

思路

- 方法1
从后先前找,找到连续的两个数,且arr[i-1]<arr[i],在下标>=i中找到最小的大于arr[i-1]的数arr[j]【由于下标>=i是递减的,所以可以从后向前比较得到】,交换arr[i-1]和arr[j],此时下标>=i仍然是递减的【nums[i~j-1]>=nums[j]>nums[i-1]>=nums[i->]】,最后把下标>=i进行翻转【当类似54321时,i=0】
- 方法2
代码
//方法1
class Solution {
public void nextPermutation(int[] nums) {
if(nums.length==1) return ;
int i=nums.length-1;
while(i>=1 && nums[i]<=nums[i-1]) i--;
//下标i-1是,i是
if(i>0){
//此时下标i~len-1是逆序排序
int j=nums.length-1;
//从后往前找,找到第一个大于nums[i]的,即在下标i~len-1中最小的大于nums[i]的数
// 交换之后,下标i+1~len-1还是倒排序
while(j>i-1 && nums[j]<=nums[i-1]) j--;
int t = nums[i-1];
nums[i-1]=nums[j];
nums[j]=t;
}
int m=i,n=nums.length-1;
while(m<n) {
int t = nums[m];
nums[m]=nums[n];
nums[n]=t;
m++;
n--;
}
}
}
//方法2
class Solution {
public void nextPermutation(int[] nums) {
if(nums.length==0 || nums.length==1) return ;
int i=nums.length-2;
for(; i>=0; i--) {
if(nums[i]<nums[i+1])
break;
}
if(i>=0) {
int j=nums.length-1;
for(; j>i; j--) {
if(nums[j]>nums[i]) break;
}
int t=nums[i];
nums[i]=nums[j];
nums[j]=t;
}
int m=i+1,n=nums.length-1;
while(m<n) {
int t = nums[m];
nums[m]=nums[n];
nums[n]=t;
m++;
n--;
}
}
}

本文深入解析了实现获取下一个排列的函数的算法,该算法将给定数字序列重新排列成字典序中下一个更大的排列。若不存在更大排列,则重排为最小的升序排列。文章详细介绍了两种方法,包括寻找关键元素并进行交换,最后翻转部分序列的步骤,确保原地修改且仅使用常数空间。
1493

被折叠的 条评论
为什么被折叠?



