数据结构与算法--将数组排成最小的数
將數組排成最小的數
-
題目:輸入一個正整數的數組,將數組中所有數字拼接在一起排列成一個新的數,打印能拼接出來的所有數字中最小的一個,
-
案例:輸入數組{12,4,55},則能打印出最小的數組是:12455
-
首先還是最簡單的做法,我們求出數組中所有數字的全排列,然后將每個排列的情況拼接成一個新的數字,比較得到最小的數字情況。求數組的全排列問題我們在之前的文章:數據結構與算法–字符串的排列組合問題
-
更具排列組合知識,n個數組共有n!個排列,當數組元素比較多的時候,時間復雜度會是一個非常大的數值,運行會非常慢,應該有更快的方案。
-
常規優化:窮舉法是為了避開了一個選擇交換的過程,如果只有兩個元素,我們找出小的放到前面,那這個題目就轉成了一個找數組的排序規則的過程。數組根據這個排序規則排列成一個最小的數字。要確定排序規則,就需要比較兩個數字,也就是給出 m,n兩個數,我們需要確定一個排序規則判斷m,n那個應該在前面,這不是比較數字大小的問題。
-
根據題目要求,兩個數字m,n,能拼出mn,nm兩個數字。
- 如果mn < nm,那么我們應該輸出mn,也就是m應該在n前面,我們定義m 小于 n
- 如果mn > nm,那么我們應該輸出nm,也就是n在m前,我們定義n 小于 m
- 同樣mn = nm定義 m= n
- 以上中 > < = 是我們數學意義上的比較,而大于,小于,等于,是我們自己定義的大小關系。
-
那么我們接下來需要考慮的是怎么去拼接數字,當給出數字,m,n,我們直接計算的方式得到mn,nm的關系并不難。但是還有一個關鍵問題,當mn拼接后得到數字無法用int表達的時候,超過int類型的范圍那么我們就不能用普通的計算方式。有一個潛在的大數問題讓我必須用字符串的方式來計算。
-
大數問題用字符串解決,字符串的比較問題,因為此處mn, nm 兩個數必然是兩個長度相等的字符串,那么比較他大小只需要按照字符串的大小比較規則就可以了。
-
基于以上分析,我們可以先對數組中的所有數組進行快速排序
-
排序規則用我們自定義規則,
-
從小到大排序后,將所有數字依次拼接,就得到了最小值。
-
經如上分析有如下代碼:
后續問題
-
如上實現方案中有兩個問題:
- 第一我定義了一種新的比較兩個數的規則,但是這種規則是我們想出來的,并不是定理或者公
- 第二我們定義的是比較兩個數的規則,但是用它來排序一個包含多個數字的數組,最終得到的是否是我們需要的的最小數字?
-
那么以上兩點我們必須給出嚴格的數學證明,來確保方案的準確:
-
第一,證明之前訂閱的比較規則有效性。一個比較規則有效,需滿足三個條件,自反性,對稱性,傳遞性
- 自反性: 顯然,如果ab = ba, 那么 a等于b
- 對稱性: 如果a 小于 b,則ab < ba, 所以ba > ab,因此b 大于 a
- 傳遞性: 如果a 小于 b, 則 ab < ba。 假設a, b都是十進制表示時候,分別有1位,m位,有如下推斷
如果有a 小于b
ab = a * 10 m + b
ba = b* 101 + a
若 ab < ba
有 a * 10 m + b < b* 101 + a
a * 10 m - a < b* 101 - b
a(10m-1) < b(101-1)
a/(101-1) < b/(10m-1)
同時如果有b 小于c,則bc < cb,同樣假設c十進制n位,與以上證明一致,得到
b/(10m -1) < c(10n -1)
綜上: a/(101-1) < b/(10m-1) < c(10n -1)
a/(101-1) < c(10n -1)
a(10n -1) < c(101-1)
a * 10n + c < c * 101+a
ac < ca
a<c
-
如上證明了這種比較規則滿足自反性,對稱性,傳遞性,是一種有效的比較規則,
-
以下還需要證明根據如上規則將數組排序后,將數組中所有數字拼接起來得到的確實是最小值。
-
略(太難了)
上一篇:數據結構與算法-- 數組中出現次數超過一半的數字(時間復雜度的討論)
下一篇:數據結構與算法–丑數
總結
以上是生活随笔為你收集整理的数据结构与算法--将数组排成最小的数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求生之路2闪退怎么办
- 下一篇: 数据结构与算法--丑数