【面试题45 把数组排成最小的数】
输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。
Leetcode题目对应位置: 面试题45:把数组排成最小的数
思路:其实这就是一个排序问题,只不过排序规则不是常规的比较大小。约定如下排序规则:对于数字 x 和 y,若 concat(x,y) > concat(y,x),则 x > y。其中 concat() 为拼接操作。比如 x = 30,y = 3,concat(x, y) = 303,concat(y,x) = 330,所以 y > x。
这样排序就可以得到最小的拼接数字,在书上是有证明的,如果不知道这个结论这道题还真不好做。
按照以上排序规则,对数组中元素进行排序,可以使用快排来做:
# 快速排序
def quickSort(self, nums, low, high):
i, j = low, high
if low < high:
temp = nums[low]
while i != j:
# 定制排序规则
while j > i and int(str(nums[j]) + str(temp)) > int(str(temp) + str(nums[j])): j -= 1
if i < j:
nums[i] = nums[j]
i += 1
while i < j and int(str(nums[i]) + str(temp)) < int(str(temp) + str(nums[i])): i += 1
if i < j:
nums[j] = nums[i]
j -= 1
nums[i] = temp
self.quickSort(nums, low, i-1)
self.quickSort(nums, i+1, high)
return nums
整道题的代码:
class Solution:
def minNumber(self, nums: List[int]) -> str:
res = self.quickSort(nums, 0, len(nums)-1)
res = [str(i) for i in res]
return "".join(res)
def quickSort(self, nums, low, high):
if low >= high: return # 递归边界
i, j = low, high
temp = nums[low]
while i != j:
while j > i and int(str(nums[j]) + str(temp)) > int(str(temp) + str(nums[j])): j -= 1
if i < j:
nums[i] = nums[j]
i += 1
while i < j and int(str(nums[i]) + str(temp)) < int(str(temp) + str(nums[i])): i += 1
if i < j:
nums[j] = nums[i]
j -= 1
nums[i] = temp
self.quickSort(nums, low, i-1)
self.quickSort(nums, i+1, high)
return nums
时间复杂度:快排时间 O ( n l o g n ) O(nlogn) O(nlogn) 和主函数 O ( n ) O(n) O(n) 的平均时间复杂度为 O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度: O ( n ) O(n) O(n),额外创建了原数组对应的字符串列表