劍指Offer 45 把陣列排成最小的數

2021-09-11 02:59:55 字數 4029 閱讀 4488

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

例:

輸入陣列, 列印321323。

排列出所有的組合,比較出最小的,輸出。

時間複雜度:o(n!)

空間複雜度:o(n!)

考察最小組合的形式,遵從下面的規律:1、首位小的靠前 2、首位相同,次位小的靠前 3、位數少的靠前。因此等價於比較a + b 和 b + a。下面證明以』a』 + 『b』 和 『b』 + 『a』 的大小順序排列在多個數字時仍然成立。假設』a』 + 『b』 和 『b』 + 『a』。下面證明以』a』 + 『b』 和 『b』 + 『a』 的大小順序排列在多個數字時仍然成立。假設ab > ba,說明』a』 > 『b』,則若 bc > cb,『b』 > 『c』,有:a∗1

0db+

b>b∗

10da

+a

a*10^ + b > b*10^ + a

a∗10db

+b>b∗

10da

+a,可得a/(

10da

−1

)>b/

(10d

b−1)

a/(10^ -1) > b/(10^-1)

a/(10d

a−1)

>b/

(10d

b−1)

,同理,b/(

10db

−1

)>c/

(10d

c−1)

b/(10^ -1) > c/(10^-1)

b/(10d

b−1)

>c/

(10d

c−1)

,因此a/(

10da

−1

)>c/

(10d

c−1)

a/(10^ -1) > c/(10^-1)

a/(10d

a−1)

>c/

(10d

c−1)

,所以ac > ca。比較具有傳遞性。因此只要將普通排序中比較兩個元素大小的關係,用字串比較替代即可。

時間複雜度:o(nlogn)使用快排

空間複雜度:o(1)

def

sort_array_for_min_number

(nums)

:"""

:param nums: int list

:return: min number string

"""from functools import cmp_to_key

nums =

[str

(i)for i in nums]

nums.sort(key = cmp_to_key(

lambda a,b:-1

if a + b < b + a else1)

)return

''.join(nums)

.lstrip(

'0')

or'0'

python2

list

.sort(

cmp=

none

, key=

none

, reverse=

false

)python3

list

.sort( key=

none

, reverse=

false

)

python2

list.sort(cmp=none, key=none, reverse=false)

引數cmp – 可選引數, 如果指定了該引數會使用該引數的方法進行排序。

key – 主要是用來進行比較的元素,只有乙個引數,具體的函式的引數就是取自於可迭代物件中,指定可迭代物件中的乙個元素來進行排序。

reverse – 排序規則,reverse = true 降序, reverse = false 公升序(預設)。

在python3中沒有cmp引數,需要借助functools.cmp_to_key,將用於比較的func轉換成key引數需要的函式,在key引數中實現cmp引數的功能。

def

cmp_to_key

(mycmp)

:"""convert a cmp= function into a key= function"""

classk(

object):

__slots__ =

['obj'

]def

__init__

(self, obj)

: self.obj = obj

def__lt__

(self, other)

:# less than

return mycmp(self.obj, other.obj)

<

0def

__gt__

(self, other)

:# greater than

return mycmp(self.obj, other.obj)

>

0def

__eq__

(self, other)

:# equal

return mycmp(self.obj, other.obj)==0

def__le__

(self, other)

:# less equal

return mycmp(self.obj, other.obj)

<=

0def

__ge__

(self, other)

:# greater equal

return mycmp(self.obj, other.obj)

>=

0 __hash__ =

none

return k

cmp_to_key函式將自定義的cmp函式轉換成了乙個類k,而k具有使用mycmp函式規定的比較的5種內建方法。list.sort(key = mykey)時,比較a、b兩個元素時,實際比較的是mykey(a)、mykey(b)這兩個類k的例項,根據比較符號是<、>、==、<=、>=分別呼叫__lt__、__gt__、__eq__、__le__、__ge__內建方法。此時結果就會是mycmp(a, b)。

因此,在構造mycmp時,我們希望』a』 + 『b』 >= 『b』 + 'a』時,mycmp(a, b) > 0 == true。

注意,此處使用lambda可以使執行速度更快。

給定一組非負整數,重新排列它們的順序使之組成乙個最大的整數。

示例 1:

輸入: [10,2]

輸出: 210

示例 2:

輸入: [3,30,34,5,9]

輸出: 9534330

說明: 輸出結果可能非常大,所以你需要返回乙個字串而不是整數。

class

solution

:def

largestnumber

(self, nums)

:"""

:type nums: list[int]

:rtype: str

"""from functools import cmp_to_key

nums =

[str

(num)

for num in nums]

nums.sort(key = cmp_to_key(

lambda a,b:

1if a+b))

return

''.join(nums)

.lstrip(

'0')

or'0'

劍指offer 45 把陣列排成最小的數

輸入乙個正整數陣列,把陣列裡所有數字拼接起來排成乙個數,列印能拼接出的所有數字中最小的乙個。例如輸入陣列,則列印出這三個數字能排成的最小數字為321323。思路1 根據全排列,將三個數字的全排列全寫出來,然後比較大小,這種辦法在數比較多時,效率不高。思路2 先比較前兩個數字m和n排列的大小 mn和n...

把陣列排成最小的數(劍指offer 45)

輸入乙個正整數陣列,把陣列裡所有的數拼接為乙個數,列印出能拼接出的所有數字中最小的乙個。比如輸入 輸出 321323.這道題其實是希望我們能找到乙個排序規則,陣列根據這個排序規則排列後能排成乙個最小的數。要確定排序規則,就要比較兩個數字,也就是給出兩個數字m n,我們需要確定乙個規則判斷m和n哪個應...

劍指offer 45 把陣列排成最小的數

輸入乙個正整數陣列,把陣列裡所有數字拼接起來排成乙個數,列印能拼接出的所有數字中最小的乙個。例如輸入陣列,則列印出這三個數字能排成的最小數字為321323。直接遍歷所有可能的結果,找出最小值。具體流程是先用二維陣列儲存所有可能的排列結果,然後遍歷所有結果找出最小值,最後把這個最小值轉成string即...