题目:
给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。
示例 1:
输入: [10,2] 输出: 210 示例 2:
输入: [3,30,34,5,9] 输出: 9534330 说明: 输出结果可能非常大,所以你需要返回一个字符串而不是整数。
- - 简单分析
拿到题目之后,略一分析,很快得出这是一道排序题,按照某种顺序排序。
具体怎么排,需要一些例子验证你的猜想。
我们知道sort()有一个参数key,可以传入一个方法,告诉sort按照key排序,但此题无法使用单参数的key,因为试了一下,发现每个元素的权重并不只跟自己有关。
例如你最初可能这样认为,先按每个数的首位数(最左边的数字)排序,大的在前,
首位数相同,则比较第二位……依次进行,直到最后一位。题目中第二个例子就是很好的说明,9,5,34,3,30,你很快发现这里有一个问题,3夹在34和30中间——我们的想法很好,但一遇到参差不齐的位数时就不好办了。
- - 解题思路
我们需要一种更好的方法表示元素的权重。
这个题目说白了,也就是**按照某种权重,对数组进行排序**。
这种权重就是:假设两个数a和b,若a连b得到的整数比b连a大,则a的权重>b的权重,在排列成整数时,a就该在前面。
(其中a连b表示a在前,b连a表示b在前。)
有了这个思路,我们就可以把以前学过的各种排序算法拿过来直接用,只需要把其中的>,<,=替换成上面的方法(可以把上面的思路def一个函数)。
当然也可以直接用sort,python2时代sort有一个cmp参数,是可以直接把比较函数带进去的,python3没了,只留下key和reverse。
现在的cmp需要 from functools import cmp_to_key。
下面是解题代码:
class Solution:
def largestNumber(self, nums):
"""
:type nums: List[int]
:rtype: str
"""
if max(nums) == 0:
return '0'
nums = list(map(str, nums))
from functools import cmp_to_key
nums.sort(key=cmp_to_key(lambda a,b: int(a+b)-int(b+a)), reverse=True)
return ''.join(nums)
有人说数有可能很大,所以应该用字符串比较大小,那么nums.sort()可以这样写:
cmp = lambda a, b: 1 if (a + b) > (b + a) else -1 if (a + b) < (b + a) else 0
nums.sort(key=cmp_to_key(cmp), reverse=True)
另外,现在cmp_to_key长这样:
def cmp_to_key(mycmp):
"""Convert a cmp= function into a key= function"""
class K(object):
__slots__ = ['obj']
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) < 0
def __gt__(self, other):
return mycmp(self.obj, other.obj) > 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) <= 0
def __ge__(self, other):
return mycmp(self.obj, other.obj) >= 0
__hash__ = None
return K
也挺简单的,相当于把>,<,=重新改造了一下。