31.Next Permutation
题目链接:https://leetcode.com/problems/next-permutation/description/
题目大意:其实是C++里面的求解全排列的下一个排列的函数。然后这里用Java实现也是极好的。其实是可以用在全排列里的,具体可以看46题:http://www.cnblogs.com/cing/p/7857730.html。不看例子了,题目意思可以看这篇博文:http://blog.csdn.net/qq575787460/article/details/41215475。
法一(借鉴):思想借鉴的上面那篇博文的,挺清晰的,第一步,从后往前找到第一个前一个数小于后一个数的下标pre;第二步,从后往前找到第一个数大于前面那个数的下标post;第三步,交换前面找到的两个下标值的数,让大数换到前面;第四步,将pre下标后面的数都reverse一下,也就是将降序转为升序。代码如下(耗时24ms):
1 public void nextPermutation(int[] nums) { 2 int length = nums.length; 3 int pre = 0, post = 0;//pre标记前面的第一个小数,即nums[pre]<nums[pre+1],post标记后面的第一个大数,即nums[post]>nums[pre] 4 boolean mark = false;//标记是否是降序序列 5 //从后往前找,找到第一个前面的数小于后面的数的下标 6 for(int i = length - 1; i > 0; i--) { 7 if(nums[i - 1] < nums[i]) { 8 mark = true; 9 pre = i - 1; 10 break; 11 } 12 } 13 //从后往前找,找到第一个比前面标记的数大的数的下标 14 for(int i = length - 1; i > 0; i--) { 15 if(nums[i] > nums[pre]) { 16 post = i; 17 break; 18 } 19 } 20 int mid = (length - pre - 1) / 2; 21 //如果直接是降序,直接反转即可 22 if(mark == false) { 23 for(int i = pre; i <= (pre + mid); i++) { 24 int t = nums[i]; 25 nums[i] = nums[--length]; 26 nums[length] = t; 27 } 28 /* for(int i = 0; i < nums.length; i++) { 29 System.out.println(nums[i]); 30 }*/ 31 return; 32 } 33 int tmp = nums[pre]; 34 nums[pre] = nums[post]; 35 nums[post] = tmp; 36 //反转后面的降序序列为升序序列 37 for(int i = pre + 1; i <= (pre + mid); i++) { 38 int t = nums[i]; 39 nums[i] = nums[--length]; 40 nums[length] = t; 41 } 42 /* for(int i = 0; i < nums.length; i++) { 43 System.out.println(nums[i]); 44 }*/ 45 }