LeetCode-031-下一个排列
思路
结合样例来分析,假设样例为 [1,3,5,4,1]:
- 从后往前找,找到第一个下降的位置,记为 k。注意k 以后的位置是降序的。 在样例中就是找到 3
- 从 k 往后找,找到最小的比 k 要大的数。 找到 4
- 将两者交换。注意此时 k 以后的位置仍然是降序的。
- 直接将 k 以后的部分翻转(变为升序)。
注意:如果在步骤 1 中找到头部还没找到,说明该序列已经是字典序最大的排列。按照题意,我们要将数组重新排列成最小的排列。
代码
class Solution {
public void nextPermutation(int[] nums) {
int n=nums.length;
int k=n-1;
//从后到前寻找分界点
while(k-1>=0&&nums[k-1]>=nums[k])k--;
//如果是分界点时0,那么直接逆序输出
if(k==0){
reverse(nums,0,n-1);
return;
}
int u=k;
//从分界点寻找大于nums[k-1]的最小值
while(u+1<n&&nums[u+1]>nums[k-1])u++;
//交换nums[k-1]和nums[u]
swap(nums,k-1,u);
//逆转分界点后的值
reverse(nums,k,n-1);
return;
}
//下标从a到b逆转的函数
public void reverse(int []nums,int a,int b){
int l=a,r=b;
while(l<r){
swap(nums,l++,r--);
}
}
//交换函数
public void swap(int[] nums,int a,int b){
int tmp=nums[a];
nums[a]=nums[b];
nums[b]=tmp;
}
}