我的个人微信公众号:Microstrong
微信公众号ID:MicrostrongAI
微信公众号介绍:Microstrong(小强)同学主要研究机器学习、深度学习、计算机视觉、智能对话系统相关内容,分享在学习过程中的读书笔记!期待您的关注,欢迎一起学习交流进步!
知乎主页:https://www.zhihu.com/people/MicrostrongAI/activities
题目链接:
题目描述:
解题思路:
(1)重新定义排序规则,时间复杂度
这个题目最直接的做法应该是先求出这个数组中所有数字的全排列,然后把每个排列拼起来,最后求出拼起来的数字的最大值。求数组的排列和面试题 28 “字符串的排列”非常类似,这里不再详细介绍。根据排列组合的知识,n个数字总共有n!个排列。我们再来看一种更快的算法。
这道题其实是希望我们能找到一个排序规则,数组根据这个规则排序之后能排成一个最小的数字。要确定排序规则,就要比较两个数字,也就是给出两个数字m和n, 我们需要确定一个规则判断m和n哪个应该排在前面,而不是仅仅比较这两个数字的值哪个更大。
根据题目的要求,两个数字m和n能拼接成数字mn和nm。 如果mn<nm, 那么我们应该打印出mn, 也就是m应该排在n的前面,我们定义此时m小于n;反之,如果nm<mn,我们定义n小于m。如果mn=nm,m等于n。在下文中,符号 “<”、“>” 及 “=” 表示常规意义的数值的大小关系,而文字 “大于”、“ 小于”、“等于” 表示我们新定义的大小关系。
接下来考虑怎么去拼接数字,即给出数字m和n,怎么得到数字mn和nm并比较它们的大小。直接用数值去计算不难办到,但需要考虑到一个潜在的问题就是m和n都在int能表达的范围内,但把它们拼起来的数字mn和nm用int表示就有可能溢出了,所以这还是一个隐形的大数问题 。
一个非常直观的解决大数问题的方法就是把数字转换成字符串。另外,由于把数字m和n拼接起来得到mn和nm,它们的位数肯定是相同的,因此比较它们的大小只需要按照字符串大小的比较规则就可以了。
基于以上思路,我们可以写出如下代码。
已经AC的代码:
from functools import cmp_to_key
class Solution:
def PrintMinNumber(self, numbers):
def cmp(a, b):
num1 = str(a) + str(b)
num2 = str(b) + str(a)
if num1 < num2:
return -1
elif num1 > num2:
return 1
else:
return 0
if numbers is None or len(numbers) == 0:
return ""
numbers.sort(key=cmp_to_key(cmp))
# sorted(numbers, key = cmp_to_key(cmp))
return "".join(str(num) for num in numbers)
if __name__ == "__main__":
sol = Solution()
numbers = [3, 32, 321]
print(sol.PrintMinNumber1(numbers))
(2)使用冒泡排序
# -*- coding:utf-8 -*-
class Solution:
# 使用冒泡排序
def PrintMinNumber2(self, numbers):
if numbers == None or len(numbers) <= 0:
return ""
# strNum = [str(num) for num in numbers]
strNum = list(map(str, numbers))
for i in range(len(numbers) - 1):
for j in range(i + 1, len(numbers)):
if strNum[i] + strNum[j] > strNum[j] + strNum[i]:
strNum[i], strNum[j] = strNum[j], strNum[i]
return ''.join(strNum)
if __name__ == "__main__":
sol = Solution()
numbers = [3, 32, 321]
print(sol.PrintMinNumber2(numbers))
Reference:
【1】《剑指offer》,何海涛著。
【2】 https://github.com/Jack-Lee-Hiter/AlgorithmsByPython/blob/master/Target%20Offer/%E6%8A%8A%E6%95%B0%E7%BB%84%E6%8E%92%E6%88%90%E6%9C%80%E5%B0%8F%E7%9A%84%E6%95%B0.py#L16
【3】 https://blog.csdn.net/yurenguowang/article/details/80568996
【4】 https://blog.csdn.net/u013129109/article/details/80089387
【5】 https://github.com/shenweichen/coding_interviews/blob/master/45.%E6%8A%8A%E6%95%B0%E7%BB%84%E6%8E%92%E6%88%90%E6%9C%80%E5%B0%8F%E7%9A%84%E6%95%B0/45.%E6%8A%8A%E6%95%B0%E7%BB%84%E6%8E%92%E6%88%90%E6%9C%80%E5%B0%8F%E7%9A%84%E6%95%B0.py