直接上代码
public class Solution { /* 做法是倒着遍历数组,目标是找到一个数比它前边的数大(即这个数后边的是降序排列),如果找到了那么这个数前边的那个数就是需要改变的最高位,如果找不到说明数组是倒序排列的,按照要求应该将数组倒过来。找到主要改变的最高位后要找谁和他交换,由于它前边的数不能变,所以那个数要倒着遍历[它+1,末尾]这个区间里的数,由于这个区间肯定是降序的,所以倒着找到的第一个就是应该交换的,交换之后的区间还是降序。这两步做完之后还要做一个工作,将这个区间的数变成升序(因为升序排列是最小的),由于本身就是降序,所以反转数组就行。 */ public void nextPermutation(int[] nums) { int l = nums.length; if(l < 2) return; int point = -1; //找到需要改变的最高位,找到别忘记break for(int i=l-1;i>0;i--) { if(nums[i] > nums[i-1]) { point = i-1; //记得跳出循环 break; } } //找不到的话直接反转数组 if(point == -1) { for(int i = 0;i < l/2;i++) { swmp(nums,i,l-i-1); } return; } //全排列的下一个是和当前排列差最最小的排列,所以接下来的工作就是找寻,怎么交换才能做到比现在的数组大,还要是所有可能答案中最小的 //找到那个和最高位交换的数,就是后边区间中比最高位的数要大的最小的数,用符合条件的最小的数交换才能最小 for(int i =l-1;i>point;i--) { if(nums[i] > nums[point]) { swmp(nums,point,i); break; } } //最后反转区间,升序保证最小 int end = (l+point+1)/2; for(int i = point+1;i<end;i++) { swmp(nums,i,l-(i-point)); } } public void swmp(int[] nums,int i,int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } }
时间: 2024-10-04 00:04:43