输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
示例 1:
输入: [10,2]
输出: “102”
示例 2:
输入: [3,30,34,5,9]
输出: “3033459”
提示:
0 < nums.length <= 100
说明:
输出结果可能非常大,所以你需要返回一个字符串而不是整数
拼接起来的数字可能会有前导 0,最后结果不需要去掉前导 0
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ba-shu-zu-pai-cheng-zui-xiao-de-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路1:排序—字符串排序
预求组合后的数更小,其实只需要将list转为字符串排序好就行了,需要考虑的是当两个字符串长度不同时需要分情况讨论他们的排列位置。
例如: x = 824和 y = 8247进行比较,需要len(x) > len(y)时,我们比较完了3位数,还需要继续比较,只不过比较应该是 y的第四位7和y的第一位8比较,因为按照数的组合其实就是两种:xy或者yx。其实就是比较xy和xy这两种情况哪种更小。
import functools
class Solution:
def minNumber(self, nums: List[int]) -> str:
# 比较两个字符串的大小:特别是长短不同时需要特殊处理
def cmp_new(x, y):
i, j = 0, 0
while i < len(x) and j < len(y):
if x[i] < y[j]:
return -1
elif x[i] > y[j]:
return 1
else:
i += 1
j += 1
# print(i, j, x, y)
if i == len(x):
i = 0
while j < len(y):
if y[i] < y[j]: # xy : yx
return -1
elif y[i] > y[j]:
return 1
else:
j += 1
if j == len(y):
j = 0
while i < len(x):
if x[i] < x[j]: # xy : yx
return -1
elif x[i] > x[j]:
return 1
else:
i += 1
if len(x) > len(y):
if x[-1] > x[0]:
return 1
else:
return -1
if len(y) > len(x):
if y[-1] > y[0]:
return -1
else:
return 1
return 0
nums = [str(n) for n in nums]
nums.sort(key=functools.cmp_to_key(cmp_new))
# print(nums)
return ''.join(nums)
思路2:排序-2
思路1的排序函数过于复杂,写的比较麻烦,其实可以直接将xy和yx拼接为两个新字符串,直接比较即可。
import functools
class Solution:
def minNumber(self, nums: List[int]) -> str:
# 比较两个字符串的大小:特别是长短不同时需要特殊处理
def cmp_new(x, y):
if x + y > y + x:
return 1
else:
return -1
nums = [str(n) for n in nums]
nums.sort(key=functools.cmp_to_key(cmp_new))
return ''.join(nums)