1. 程式人生 > 其它 >陣列的合併和升序排列_每日“力扣”系列10 下一個排列

陣列的合併和升序排列_每日“力扣”系列10 下一個排列

技術標籤:陣列的合併和升序排列

今天繼續力扣陣列標籤的演算法題,力扣第31題,難度等級為中等,題目描述如下:

0f9695af3a28e1b831b3de4d60181ee7.png

題目要點概括如下:

1、輸入部分為一個有順序的陣列,按照數字的前後順序,這個數字代表著一個位數不定的數字,這裡程它為原數字。

2、關於輸出,要獲得一個修改後的數字,如果原來陣列中數字的其他排列組成的數字比原數字要大,那就輸出與原數字最接近的更大值;如果原數字已經是原始陣列所包含數字所能組成的最大數字,那就將這個陣列整理為升序陣列。

33、整個處理過程要求在原陣列上完成,而且額外使用的空間有限且在整個過程中不發生變化。

通過分析一個數字,我們可以知道,當所包含的數字從高位到低位,是按照降序排列的(也就是高位上的數字始終比低一個位上的數字要大),那這個數字就是這些數字所能組成的最大數字;同理,如果這些數字時按照升序排列的,那這個數字就是這些數字所能組成的最小數字。如此看來,判斷是否還有更大的數字存在,只需要判斷這個數字裡的各個位是不是按照降序排列的就OK了。

判斷陣列中從第一個到最後一個是否是按照降序,只有一個辦法,那就是遍歷,可以選擇從頭開始遍歷,當然也可以從最後一位開始遍歷。

(但是本題中使用從最後一個開始更方便,分析完整個題目就很清楚了)

我們先來處理沒有更大的數字時的情況,沒有更大的數字,那就說明這個數字最大,也就是反應了這個數字中的各個位數是降序排列的,那我們現在改為升序,就只需要將整個陣列前後顛倒一下。

再來分析存在更大值的情況。

既然存在更大值,通過之前我們的分析也可以看出,一定是存在一個位置,高位的數字小於低位的數字,那這就是我們需要進行調整的地方了。

b61404c62bb5302cceb73390b30645b8.png

那我們是將二者交換就拿到我們所要的陣列了麼?

並沒有那麼簡單。

第一,我們選擇交換的數字,應當是出現錯位的數字(圖中的數字 4 )和他的後面大於這個數字,同時是最小的數字( 圖中的數字 5 ),這樣才能保證更改的這一位相對來說變化最小。

(由於要找之後的幾位中大於該位且最小的,而且這部分是降序的,所以從後邊往前進行迴圈,出現的第一個大於要錯位數字的數,就是我們需要的,這也就是我們選擇從後面進行迴圈的原因)

第二,因為在交換後,這兩位的後面幾位仍然存在著升序和降序的問題。而之前我們也分析過,一個位數確定的數字,要拿到最小值,就一定是升序的。所以,要拿到最接近原數字的新數字,還需要交換過的後面幾位進行區域性的升序處理。

程式碼如下:

public 

位置①處程式碼實現找到要更換為位置

位置②和③分別是實現交換和排列功能。

此外,看了眼官方給的程式碼,用的是whil迴圈,更加簡潔,也貼出來:

public class Solution {
    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 reverse(int[] nums, int start) {
        int i = start, j = nums.length - 1;
        while (i < j) {
            swap(nums, i, j);
            i++;
            j--;
        }
    }

    private void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

作者:LeetCode
連結:https://leetcode-cn.com/problems/next-permutation/solution/xia-yi-ge-pai-lie-by-leetcode/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

另:官方解法給出了了動圖,更方便理解,由於下載失敗,貼出連線:

力扣​leetcode-cn.com

今天的刷題就是這樣。

這個系列主要來記錄和回滾,如果感覺寫的還能看,歡迎轉發評論、點贊關注喔

按照慣例,倒一下前兩天縮寫:

昨天:

王進林:菜雞刷LeetCode系列記錄8 刪除重複項​zhuanlan.zhihu.com 王進林:菜雞刷LeetCode系列記錄9 移除元素​zhuanlan.zhihu.com

前天:

王進林:菜雞刷LeetCode系列記錄7 四數之和​zhuanlan.zhihu.com

下一天的:

王進林:菜雞刷LeetCode系列記錄11 搜尋旋轉排序陣列​zhuanlan.zhihu.com