实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/next-permutation
//理解题意:简单的看就是,你把数组连成一个数,得到的结果应该是跟这个数最近且比他大的数,如果这个数已经最大,就返回组合的最小数 public void nextPermutation(int[] nums) { int index = -1; //从后向前遍历,所以界限为:i > 0 for(int i = nums.length -1; i>0; i--){ //找到前一个比后一个小的数,说明不是趋势递减 if(nums[i-1] < nums[i]){ //记录不是趋势递减的索引位置 index = i-1; break; } } //若是找到了不是趋势递减的索引位置 if(index != -1){ //需要先从后向前遍历找到比索引位置的值大的数字 for(int i = nums.length -1; i>0; i--){ if(nums[index] < nums[i]){ //将之前找到的索引位置跟当前位置交换 swap(nums,index,i); break; } } } //如果这个数组就是趋势递减的,那么就需要数组倒置以下 //如果数组不是趋势递减的,就需要把index位置后的数组倒置下 Arrays.sort(nums,index+1,nums.length); } //数组中数据交换 public void swap(int [] nums,int start,int end){ int temp = nums[start]; nums[start] = nums[end]; nums[end] = temp; }
时间复杂度:O(n)
空间复杂度:O(1) -- 虽然借用了 Arrays.sort,但是在sort方法中借用了额外的空间,暂且不算
自己做转换也ok:
public void reverse(int [] nums,int start,int end){ while(start<end){ swap(nums,start,end); start++; end--; } }