《剑指offer》---把数组排成最小的数

本文算法使用python3实现


1. 问题

1.1 题目描述:

  输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组 $ [3,32,321] $ ,则打印出这三个数字能排成的最小数字为 $ 321323 $ 。
  时间限制:1s;空间限制:32768K


1.2 思路描述:

  大致思路
  (1)我们可以先思考只有两个数字的情况: $ [3,32] $ ,可以看出来 $ 332 > 323 $ 因此需要把数组改变为 $ [32,3] $ ;
  (2)对于有三个数字的情况: $ [3,32,321] $ 我们两两进行比较, $ 332 > 323 $ 于是,将 $ 3 $ 与 $ 32 $ 交换位置变成 $ [32,3,321] $ 而 $ 3321 > 3213 $ 于是将 $ 3 $ 与 $ 321 $ 继续交换位置到 $ [32,321,3] $ ;接着我们继续使用 $ 32 $ 进行比较,由于 $ 32321 > 32132 $ 将 $ 32 与 321 $ 进行位置交换为 $ [321,32,3] $ 此时,将数组链接起来变成 $ 321323 $ 即为最小的数。
  具体思路
  (1)先将数字列表转化成字符串链表,这样便于在一个字符串后面直接加上另外一个字符串。也就是 $ "3" + "321" = "3321" $ 。
  (2)构造一个比较函数,当 $ str1 + str2 > str2 + str1 $ 时我们认为字符串 $ str1 > str2 $ 。
  (3)将字符串列表按照比较函数的规定进行冒泡排序(或其它方法排序),将定义为”大”的字符串放到最后。而”小”的字符串放在前面。最后将字符串列表链接起来,便是所求。
  注意:在python2.x中可直接对 sort() 函数进行比较函数cmp的传参,可以利用sort()函数直接对字符串列表进行排序。但是,对于python3.x取消了sort()函数中的cmp参数

1.3 程序代码:

(1)方法一:

class Solution:
    def theMax(self, str1, str2):
        '''定义字符串比较函数'''
        return str1 if str1+str2 > str2+str1 else str2

    def PrintMinNumber(self, numbers):
        """使用冒泡进行排序(把最大的放最后)"""
        string = [str(num) for num in numbers]
        res = []
        flag = True
        count = len(string) - 1
        while flag and  count > 0:
            flag = False
            for i in range(len(string)-1):
                if self.theMax(string[i], string[i+1]) == string[i]:
                    temp = string[i]
                    del string[i]
                    string.insert(i+1, temp)
                    flag = True
            count -= 1
        string = ''.join(string)
        return string

(3)方法二(仅python2.x可用):

class Solution:
    def cmp(self, a, b):
        '''定义比较函数'''
        ab = int(a+b)
        ba = int(b+a)
        return 1 if ab > ba else -1

    def PrintMinNumber(self, numbers):
        string = [str(num) for num in numbers]
        string.sort(self.cmp, reverse=True)
        return ''.join(string)

猜你喜欢

转载自www.cnblogs.com/lliuye/p/9159152.html