Leetcode31. Next Permutation
这题主要是理排列的思路,归纳排列的规则,还挺难的。
看了discuss后才做出来。
public class NextPermutation31 { public void nextPermutation(int[] nums) { int i = nums.length-2; while(i>=0&&nums[i+1]<=nums[i]) { 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); } private void swap(int[] nums,int i,int j) { int temp = nums[i]; nums[i]=nums[j]; nums[j]=nums[i]; } private void reverse(int[] nums,int i) { int j = nums.length-1; while(i<j) { swap(nums,i++,j--); } } }
13ms,30%.
猛地看有点懵逼,这里说明一下。
在lexicographically条件下,下一个排列应该是相对上个排列更降序一些。即,整体的走向是将升序逐渐变为降序。
比如 12345为升序,下一个是12354,最后两个降序。再下个12435,将4提前,后面的Reverse一下升序,提前操作其实就是和3换位。
所以需要交换和reverse操作,先写出函数来。
然后流程是,倒着找,先找最后的一对相邻的升序的元素a[i]和a[i+1]。这时,a[i]右边都是非升序的(降序和相等),无法再往下排列了,故需要找到比a[i]大的最小的元素,放在i位置上(和a[i]互换)。
找的方法就是从右开始找,找到第一个比a[i]大的数a[j],互换。
之后,右边相当于要成为一个新的排列,故要变为升序,而a[i]a[j]互换后,右边应该正好是降序的(因为右边开始非升序,找的是第一个比a[i]大的数,即a[j]右边都比a[i]小,左边都大,换完依然是非升序),故reverse即可。
看了下8ms答案,思路都是一样的,而且也没做什么优化,所以这样就可以了。

浙公网安备 33010602011771号