整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。例如,arr = [1,2,3]
,以下这些都可以视作 arr
的排列:[1,2,3]
、[1,3,2]
、[3,1,2]
、[2,3,1]
。整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。
本题是一个固定的思路,步骤如下:
1.从后往前,找到第一个相邻的升序元素对,记录下元素对中前一个元素i
2.此时的i有两种情况,一种是5123这种,可以找到其中的升序子序列;一种是5321,找不到其中的升序子序列,所以用如下代码从后往前找到第一个相邻的升序数组:
while(i >= 0 && nums[i] >= nums[i + 1]){
i--;
}
假如是情况一,i>=0,将会进行额外的交换步骤;假如是情况二,i = -1,直接翻转数组即可。
3.如果是情况一,需要进行交换,从后向前找到比nums[i]的第一个数字nums[j],将nums[i]与nums[j]进行交换。如果是情况二,则不需要进行进行查找和交换的步骤。具体是通过if判断i是否大于等于0来判断的
4.无论是情况一还是情况二,都需要进行数组的翻转。举例来说,对于情况一,nums[i]的值是2,nums[j]的值是3,进行2和3之间的翻转。对于情况二,需要进行整个数组的翻转。
在写函数时,需要传入数组nums参数,不然无法做到交换。
class Solution {
public void nextPermutation(int[] nums) {
int i = nums.length - 2;
while(i >= 0 && nums[i] >= nums[i + 1]){
i--;
}
if(i >= 0){
int j = nums.length - 1;
while(j >= 0 && nums[j] <= nums[i]){
j--;
}
swap(nums,i,j);
}
reverse(nums,i + 1);
}
public void swap(int[] nums,int a,int b){
int temp = nums[a];
nums[a] = nums[b];
nums[b] = temp;
}
public void reverse(int[] nums,int start){
int left = start;
int right = nums.length - 1;
while(left < right){
swap(nums,left,right);
left++;
right--;
}
}
}