31. Next Permutation

題目:java

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.數組

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).ide

The replacement must be in-place, do not allocate extra memory.spa

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1code

連接: http://leetcode.com/problems/next-permutation/blog

題解:ip

正常倒序應該是654321,假如652431,則2爲inversion,而且next permutation應該爲653124。ci

方法是從後向前找inversion,找到第一個inversion,如上例中,而後繼續從後向前判斷,假如從數組尾部到inversion元素 i 間有數字大於i, 則swap i 和這個數字,因爲swap以後依然是倒序,因此咱們reverse i 到 nums.length -1。element

Time Complexity - O(n), Space Complexity - O(1)。leetcode

public class Solution {
    public void nextPermutation(int[] nums) {       // in place, so we consider swap
        if(nums == null || nums.length == 0)
            return;
        
        for(int i = nums.length - 2; i >= 0; i--) {     //find first inversion from end  e.g. - 654231  
            if(nums[i] < nums[i + 1]) {
                for(int j = nums.length - 1; j >= i; j--) {
                    if(nums[j] > nums[i]) {             
                        swap(nums, i, j);                   //swap inversion element and swap i, keep descendent order
                        reverse(nums, i + 1, nums.length - 1);  // i + 1 to nums.length - 1 if possible
                        return;
                    }
                }
            }
        }
        
        reverse(nums, 0, nums.length - 1);              // no inversion
    }
    
    private void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    
    private void reverse(int[] nums, int lo, int hi) {
        while(lo < hi)
            swap(nums, lo++, hi--);
    }
}

 

 

題外話: 

1-20-2016:

最近刷題的勁頭減弱,身體也並不很好,因爲壓力老是大失眠。給Amazon和Microsoft投遞出了簡歷都是石沉大海,好挫敗,經常看地裏New Graduate很容易就能拿到onsite或者video interview,只回答幾個簡單問題就能拿到offer,很羨慕。有時候甚至想辭職去讀一個名校CS學位。

負能量比較重。

但願二刷時好好鍛鍊好思惟, 沉住氣,耐心按照計劃執行。已經付出這麼多時間和努力,接下來就是要堅持下去。付出 + 堅持,我相信必定會有回報。本身給本身鼓勵吧。

 

二刷:

主要仍是用以前的辦法。先從數組後部向前部找第一個正序的數對,好比(2, 3),(2, 4)一類。找到這第一個正序隊以後,咱們要另外設置一個變量j,也是從數組後部向前部查找,找第一個值nums[j] > nums[i],好比(2, 3, 1)。 找到以後咱們要swap(i, j),這樣就能保持 i + 1到 nums.length - 1這些數字呈現一個降序的排列,而後咱們再reverse(i + 1, nums.length - 1)就能夠了。假如數組中沒有正序的數對,那麼咱們根據題意要對整個數組進行逆序。

二刷時看了一下discuss區yavinci大神的代碼,真是簡潔又漂亮,很是羨慕。

Java:

Time Complexity - O(n), Space Complexity - O(1)

public class Solution {
    public void nextPermutation(int[] nums) {
        if (nums == null || nums.length == 0) {
            return;
        }
        for (int i = nums.length - 2; i >= 0; i--) {
            if (nums[i] < nums[i + 1]) {
                for (int j = nums.length - 1; j > i; j--) {
                    if (nums[j] > nums[i]) {
                        swap(nums, i, j);
                        reverse(nums, i + 1, nums.length - 1);
                        return;
                    }
                }
            }
        }
        reverse(nums, 0, nums.length - 1);
    }
    
    private void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    
    private void reverse(int[] nums, int i, int j) {
        while (i < j) {
            swap(nums, i++, j--);
        }
    }
}

 

 

三刷:

Java:

public class Solution {
    public void nextPermutation(int[] nums) {
        if (nums == null || nums.length < 2) return;
        int len = nums.length;
        for (int i = len - 2; i >= 0; i--) {
            if (nums[i] < nums[i + 1]) {
                for (int j = len - 1; j > i; j--) {
                    if (nums[j] > nums[i]) {
                        swap(nums, i, j);
                        reverse(nums, i + 1, len - 1);
                        return;
                    }
                }
            }
        } 
        reverse(nums, 0, len - 1);
    }
    
    private void swap(int[] nums, int i, int j) {
        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    
    private void reverse(int[] nums, int i, int j) {
        while (i < j) swap(nums, i++, j--);
    }
}

 

 

Reference:

https://leetcode.com/discuss/8472/share-my-o-n-time-solution

https://leetcode.com/discuss/38247/algorithm-wikipedia-implementation-permutations-permutations

https://leetcode.com/discuss/70881/easiest-java-solution 

https://leetcode.com/discuss/47076/1-4-11-lines-c

相關文章
相關標籤/搜索