題目連接:https://leetcode.com/problems/next-permutation/description/html
題目大意:實際上是C++裏面的求解全排列的下一個排列的函數。而後這裏用Java實現也是極好的。實際上是能夠用在全排列裏的,具體能夠看46題:http://www.cnblogs.com/cing/p/7857730.html。不看例子了,題目意思能夠看這篇博文:http://blog.csdn.net/qq575787460/article/details/41215475。ide
法一(借鑑):思想借鑑的上面那篇博文的,挺清晰的,第一步,從後往前找到第一個前一個數小於後一個數的下標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 }