剑指offer:Python 把数组排成最小的数

题目描述

输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。

思路及Python实现

  • 将数组中的数字变成字符串连接起来,排成一个最小的数字,将“大数”往后放“小数”往前放,如何定义“大数”和“小数”?比如说数组中有两个数a和b,如果字符串拼接在一起的ab>拼接在一起的ba则:a是“大数”,b是“小数”,要排成ba,大的往后排,小的往前排!于是,这道题目变成了一个排序问题,将能把组合出来的数字变大的数字往后排。我们这里需要自己定义一个比大小的比较方法,可以用上非常多的排序方法,这里写出:冒泡,和快排

用内置的排序方式

# Python 3.x 不可用cmp()函数
class Solution:
    def PrintMinNumber(self, numbers):
        return "".join(map(str,sorted(numbers, cmp = lambda a, b : cmp(str(a) + str(b), str(b) + str(a)))))
  • 解释下:
    (1)sorted() 函数:对所有可迭代的对象进行排序操作。
    sort 与 sorted 区别:
    sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
    list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

    sorted(iterable, key=None, reverse=False)
    参数说明:

    iterable – 可迭代对象。
    key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序;一般可以传入一个lambda表达式,来定义排序规则

    reverse – 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
    有返回值,返回值:返回重新排序的列表。

例如:先按照成绩降序排序,相同成绩的按照名字升序排序

d1 = [{'name':'alice', 'score':38}, {'name':'bob', 'score':18}, {'name':'darl', 'score':28},
{'name':'christ', 'score':28}]
l = sorted(d1, key=lambda x:(-x['score'], x['name']))
print(l)

'''
[{'name': 'alice', 'score': 38}, {'name': 'christ', 'score': 28}, {'name': 'darl', 'score': 28}, {'name': 'bob', 'score': 18}]
'''

(2)map()函数:会根据提供的函数对指定序列做映射,第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
map() 函数语法:
map(function, iterable, …)
参数:
function – 函数
iterable – 一个或多个序列
返回值:
Python 2.x 返回列表。
Python 3.x 返回迭代器(一般最后需要用list全部取出)

>>>def square(x) :            # 计算平方数
...     return x ** 2
... 
>>> map(square, [1,2,3,4,5])   # 计算列表各个元素的平方
[1, 4, 9, 16, 25]
>>> map(lambda x: x ** 2, [1, 2, 3, 4, 5])  # 使用 lambda 匿名函数
[1, 4, 9, 16, 25]
 
# 提供了两个列表,对相同位置的列表数据进行相加
>>> map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
[3, 7, 11, 15, 19]

冒泡排序

class Solution:
    def PrintMinNumber(self, numbers):
        # write code here
        length = len(numbers)
        if (length == 0):
            return ''
        str_num = [str(i) for i in numbers]
        flag = False
        for i in range(length-1):
            for j in range(length - i - 1):
                if int(str_num[j+1]+str_num[j]) < int(str_num[j]+str_num[j+1]):
                    str_num[j], str_num[j+1] = str_num[j+1], str_num[j] 
                    flag =True
            if not flag:
            	break
        num = ''.join(i for i in str_num)
        # 等价于
        # num = ''
        # for i in str_num:
            # num += i
        return int(num)

快速排序

class Solution:
    # 自定义排序规则加快排
    def PrintMinNumber(self, numbers):
        # write code here
        if numbers is None or len(numbers) == 0:
            return ""
        numbers = [str(x) for x in numbers]
        pivot = numbers[0]
        less = [i for i in numbers[1:] if (pivot + i) > (i + pivot)]
        great = [i for i in numbers[1:] if (pivot + i) <= (i + pivot)]
        result = "".join(self.PrintMinNumber(less)) + pivot + "".join(self.PrintMinNumber(great))
        return result.lstrip("0")


obj = Solution()
print(obj.PrintMinNumber(['3', '23', '321']))
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值