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).

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

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,1

題意:

產生下一個序列,對給定序列進行重排,生成一個字母順序比它更大的下一個序列。

如果給定的序列已經是按字母順序排列中最大的一個了,則進行逆序排列。

算法在數組內進行,不要使用額外空間。

算法設計:

(1)從后向前遍歷,找到第一個不滿足降序的元素;若初始序列全部是降序,則i為-1,直接跳轉至(3);

(2)將該元素同它后面的元素中比它大的第一個元素交換;

(3)將該元素后的所有元素排列,使之成為最小的排列。

代碼:

    public void nextPermutation(int[] nums) {
        if(nums == null || nums.length == 0)
            return;
        //長度為1的數組
        if (nums.length == 1) {
            return;
        }
    
        //從后向前找到第一個不滿足逆序的元素
        int i = nums.length - 2; 
        for(; i >= 0 && nums[i] >= nums[i + 1]; --i); //注意,這里有=,可以排除含有重復元素的情況
        
        //從i+1位置開始,向后查找比nums[i]大的最小元素
        if(i >= 0){ 
            int j = i + 1;
            for(; j < nums.length && nums[j] > nums[i]; ++j);
            swap(nums,i,j - 1); //交換,注意是同 j - 1交換
        }
        
        //將i之后的元素逆置(這里包含一種特殊情況,若該排列已經是字典序中的最大了,則下一個序列應該是最小字典序,因此,直接在這里逆置即可)
        int k = nums.length - 1;
        i++;
        for(; i < k; i++, k--)
            swap(nums, i, k);
    }
    
    /**
     * 交換元素
     * @param array
     * @param i
     * @param j
     */
    public void swap(int[] array,int i ,int j){
        //交換
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM