1. 程式人生 > 實用技巧 >劍指offer_45_把陣列排成最小的數

劍指offer_45_把陣列排成最小的數

把陣列排成最小的數

題目連結:https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof/

題目內容:

輸入一個非負整數陣列,把數組裡所有數字拼接起來排成一個數,列印能拼接出的所有數字中最小的一個。

示例 1:

輸入: [10,2]
輸出: "102"

示例 2:

輸入: [3,30,34,5,9]
輸出: "3033459"

提示:

  • 0 < nums.length <= 100

說明:

  • 輸出結果可能非常大,所以你需要返回一個字串而不是整數
  • 拼接起來的數字可能會有前導 0,最後結果不需要去掉前導 0

題目解析

題目解析內容來自於題解中Krahetsbigkjp97

分析

題目的意思首先要明確,不是說把列表中每個數拆分開,而是,將數組合起來,組成一個最小的數。

這就轉換成了讓這個列表按照組合後數字最小的模式排序。也就是說,要定一個規則,使得列表中的數字按照這個規則從小到大排序。

現在我們就來找這個排序規則

這裡放一個示例,供大家理解。

test_list = [3, 30, 34, 5, 9]  # 示例列表

由題意,當 '30' + '3' = '303', '3' + '30' = '330' 時,'303' < '330', 則可知 '30' + '3' < '3' + '30', 也即 30 應該在陣列按照規則排序後應排在 3 前面。

同理, '30' + '34' = '3034', '34' + '30' = '3430', '3034' < '3430', 則 '30' + '34' < '34' + '30', 即 30 在 34 前面。

照此邏輯,可以類推。

則可以得出這個排序規則:x + y < y + x ===> x < y

根據這個規則,使用任何一種排序方法都可以對 指定列表進行排序,從而得到最小的排列結果。

演算法流程:
  1. 初始化:根據數字列表生成字串列表
  2. 字串列表排序:根據上面發現的規則進行字串列表的排序
  3. 返回:拼接字串列表為字串,並返回
複雜度分析:
  • 時間複雜度 O(NlogN)
    : N 為最終返回值的字元數量(字串列表 的長度 <= N); 使用快排或者內建函式的平均時間複雜度為O(NlogN), 最差為 O(N2)
  • 空間複雜度 O(N): 字串列表 佔用線性大小的額外空間
程式碼

快排方式

class Solution:
    def minNumber(self, nums):
        def fast_sort(strs):
            if len(strs) <= 1:
                return strs
            less, greater = [], []
            p = strs.pop()
            for i in strs:
                if i + p < p + i:
                    less.append(i)
                else:
                    greater.append(i)
            print(less, greater, p, type(p))
            
            return fast_sort(less) + [p] + fast_sort(greater)
        
        strs = [str(num) for num in nums]
        res = fast_sort(strs)
        return ''.join(res)

內建函式方式

class cmpSmaller(str):
    def __lt__(self, y):
        return self + y < y + self  # 字串拼接比較(兩兩比較)
    # 按由小到大來排列

class Solution:
    def minNumber(self, nums):
        res=sorted(map(str, nums),key=cmpSmaller)
        smallest = ''.join(res)
        return smallest

sort 是隻可比較 list 型別;sorted 可比較所有可迭代物件

附加說明

快排方式,無需多言。內建函式,實可深究。

內建函式方式自定義了一個類 comSmaller 繼承了 str 類。並且重寫了其 __lt__方法。這個方法就是當程式使用 < 比較時,程式內部呼叫的方法。具體解析可點此瞭解

至於為什麼 sorted 排序指定的 keycomSmaller 類,在下是在難以深究,忘大佬賜教。以供更改此文件。