题目描述:
输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。
思路:
将数组中的排列成一个最小(大)的数的基本思路是:首先将数组中的元素转换为字符串,然后看字符串拼接后的结果的大小关系。如3和32,转换成字符拼接后有两种结果: ′ 3 ’ + ′ 3 2 ′ '3’+'32' ′3’+′32′ 和 ′ 3 2 ′ + ′ 3 ′ '32' + '3' ′32′+′3′,因为 323 < 332 323 < 332 323<332,所以32必然在3前面,依次类推,最后返回数组中元素拼接后的结果。
为了保证结果不溢出,可将数组中元素拼接后的结果转换为int后再转换为str输出。
-
法1: 创建数组r存放排列后的结果,首先将原数组首元素放入,然后遍历数组中剩下的元素 n u m num num与 r i r_{i} ri中元素进行比较
- 如果 n u m < r i num < r_{i} num<ri,将其插入到 r i r_{i} ri前面,更新 r r r;否则继续往后比较
- 如果必到最后没有在 r r r中找到满足的要求的元素,则将其添加到 r r r后面
-
法2: 利用python中内置list的排序函数sort(),它需要定义比较规则,然后利用sort函数对字符串进行排序。
AC代码
法1
# -*- coding:utf-8 -*-
class Solution:
def PrintMinNumber(self, numbers):
# write code here
if numbers == []:
return ""
r = [numbers[0]]
for i in numbers[1:]:
for id in range(len(r)):
if int(str(i) + str(r[id])) < int(str(r[id]) + str(i)):
r.insert(r.index(r[id]), i)
break
elif id == len(r) - 1:
r.append(i)
return int(''.join(str(x) for x in r))
法2
class Solution:
def minNumber(self, nums: List[int]) -> str:
def sort_rule(x, y):
a, b = x + y, y + x
if a > b: return 1
elif a < b: return -1
else: return 0
strs = [str(num) for num in nums]
strs.sort(key = functools.cmp_to_key(sort_rule))
return ''.join(strs)
回溯法在LeetCode上会超出时间限制 -_-
# -*- coding:utf-8 -*-
class Solution:
def minNumber(self, nums: List[int]) -> str:
if not nums: return ''
res = []
l = len(nums)
def find(nums, path, index = 0):
if index == l:
t = path[:]
res.append(''.join(t))
return
for i in range(len(nums)):
path.append(str(nums[i]))
find(nums[:i] + nums[i + 1:], path, index + 1)
path.pop()
find(nums, [], 0)
res.sort()
return res[0]