输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1:
输入: [10,2]
输出: "102"
示例 2:
输入: [3,30,34,5,9]
输出: "3033459"
提示:
说明:
题目解析内容来自于题解中Krahets 和 bigkjp97
题目的意思首先要明确,不是说把列表中每个数拆分开,而是,将数组合起来,组成一个最小的数。
这就转换成了让这个列表按照组合后数字最小的模式排序。也就是说,要定一个规则,使得列表中的数字按照这个规则从小到大排序。
现在我们就来找这个排序规则:
这里放一个示例,供大家理解。
test_list = [3, 30, 34, 5, 9] # 示例列表
由题意,当 ‘30‘ + ‘3‘ = ‘303‘, ‘3‘ + ‘30‘ = ‘330‘ 时,‘303‘ < ‘330‘, 则可知 ‘30‘ + ‘3‘ < ‘3‘ + ‘30‘, 也即 30 应该在数组按照规则排序后应排在 3 前面。
同理, ‘30‘ + ‘34‘ = ‘3034‘, ‘34‘ + ‘30‘ = ‘3430‘, ‘3034‘ < ‘3430‘, 则 ‘30‘ + ‘34‘ < ‘34‘ + ‘30‘, 即 30 在 34 前面。
照此逻辑,可以类推。
则可以得出这个排序规则:x + y < y + x ===> x < y
根据这个规则,使用任何一种排序方法都可以对 指定列表进行排序,从而得到最小的排列结果。
快排方式
class Solution:
def minNumber(self, nums):
def fast_sort(strs):
if len(strs) <= 1:
return strs
less, greater = [], []
p = strs.pop()
for i in strs:
if i + p < p + i:
less.append(i)
else:
greater.append(i)
print(less, greater, p, type(p))
return fast_sort(less) + [p] + fast_sort(greater)
strs = [str(num) for num in nums]
res = fast_sort(strs)
return ‘‘.join(res)
内置函数方式
class cmpSmaller(str):
def __lt__(self, y):
return self + y < y + self # 字符串拼接比较(两两比较)
# 按由小到大来排列
class Solution:
def minNumber(self, nums):
res=sorted(map(str, nums),key=cmpSmaller)
smallest = ‘‘.join(res)
return smallest
sort 是只可比较 list 类型;sorted 可比较所有可迭代对象
快排方式,无需多言。内置函数,实可深究。
内置函数方式自定义了一个类 comSmaller
继承了 str
类。并且重写了其 __lt__
方法。这个方法就是当程序使用 <
比较时,程序内部调用的方法。具体解析可点此了解
至于为什么 sorted
排序指定的 key
为 comSmaller
类,在下是在难以深究,忘大佬赐教。以供更改此文档。
原文:https://www.cnblogs.com/yezigege/p/13397889.html