其他算法-032-把數組排成最小的數

題目描述

輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。例如輸入數組{3,32,321},則打印出這三個數字能排成的最小數字爲321323。

分析

  • 方法一:乍一看此題似乎是一個全排列問題,當然可以用回溯進行全排列,但是時間複雜度爲O(n!).再有明顯的更快的方法下,顯然不可取。
  • 方法二:事實上,此題是借用實際問題來考察排序,需重新定義目標之間的大小關係。在這裏我們自己定義一個規則,對拼接後的字符串進行比較。
    排序規則如下:
    • 若ab > ba, 則 a 大於 b,
    • 若ab < ba ,則 a 小於 b,
    • 若ab = ba ,則 a 等於 b;
      我們在此大小關係比較下,利用排序算法進行從小到大的排序,最後拼接轉換數字即爲最小數字。這裏使用快排,則時間複雜度爲O(nlognn\log n)。

代碼

class Solution:
    def PrintMinNumber(self, numbers):
        # write code here
        if not numbers:
            return ''
        
        numbers = list(map(str, numbers))
        self.quickSort(numbers, 0, len(numbers)-1)
        
        return int(''.join(numbers))
        
    def partation(self, numbers, left, right):
        #左右指針
        # print(left, right)
        low = left
        high = right
        
        k = numbers[low]
        while low<high:
            while low<high and self.gCmp(numbers[high], k):
                high -= 1
            
            while low<high and not self.gCmp(numbers[low], k):
                low += 1
                
            if low<high:
                numbers[low], numbers[high] = numbers[high], numbers[low]
        
        numbers[left], numbers[high] = numbers[high], numbers[left]
        
        return high
        
    def quickSort(self, numbers, left, right):
        if left < right:
            # print(left, right)
            k_idx = self.partation(numbers, left, right)
            self.quickSort(numbers, left, k_idx-1)
            self.quickSort(numbers, k_idx+1, right)
            
            
    def gCmp(self, a, b):
        return a+b>b+a

當然在python 2.x下可直接使用排序函數,自定義排序規則,得到結果:

class Solution:
    def PrintMinNumber(self, numbers):
        # write code here
        if not numbers: return ""
        numbers = list(map(str, numbers))
        numbers.sort(cmp=lambda x, y: cmp(x + y, y + x))
        return int("".join(numbers))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章