数串:给定一传数,组成最大数字

链接:https://www.nowcoder.com/questionTerminal/a6a656249f404eb498d16b2f8eaa2c60
来源:牛客网

设有n个正整数,将他们连接成一排,组成一个最大的多位整数。
如:n=3时,3个整数13,312,343,连成的最大整数为34331213。
如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613。

输入描述:
有多组测试样例,每组测试样例包含两行,第一行为一个整数N(N<=100),第二行包含N个数(每个数不超过1000,空格分开)。

输出描述:
每组数据输出一个表示最大的整数。
示例1
输入
2
12 123
4
7 13 4 246
输出
12312
7424613

时间复杂度O(n的平方)的方法

import sys
import time
def cmp(l1,l2):
    #print("l1 is",l1)
    #print("l2 is",l2)
    s1=str(l1)+str(l2)
    s2=str(l2)+str(l1)
    #print("s1 is",s1,"s2 is",s2)
    for i in range(0,len(s1)):
        #print("s1[",i,"] is",s1[i])
        if int(s1[i])>int(s2[i]):
            #print("first False")
            return  False
        if int(s1[i])<int(s2[i]):
            #print("secod True")
            return  True
    return False

#starttime = time.time()
n = int(sys.stdin.readline().strip())
l = list(map(int, sys.stdin.readline().strip().split()))
for i in range(0,n):
    for j in range(i+1,n):
        #print("current i is", i, "cur j is", j, "cur l is", l)
        if cmp(l[i],l[j]):
            l[i],l[j]=l[j],l[i]

strsl=list(map(str,l))
res=''.join(strsl)
print(res)
#endtime = time.time()
#print(endtime-starttime)

这个方法在牛客网上也能通过,但是在vm的笔试中就只有36%,因为超时。
我分析这个算法类似冒泡排序的思想,时间复杂度是O(n的平方)
对第二组实例的运行时间为14.653626680374146

我在想如何改进,查到https://blog.csdn.net/kobe2016/article/details/79144534
这篇博客里说 python自带的sorted()算法,最坏的时间复杂度是O(nlogn)
所以改用python自带的sort算法试一下
而且python3自带的sort函数不接受直接使用cmp了,要自定义比较规则,而且比较函数还不接受两个参数,如果想接受两个参数,必须调用from functools
import cmp_to_key

import sys
from functools import cmp_to_key
#import  time
def mycmp(a, b):
    ab = int(a+b)
    ba = int(b+a)
    return 1 if ab > ba else -1
#starttime = time.time()
num = int(sys.stdin.readline().strip())
l= sys.stdin.readline().strip().split()
ls=sorted(l,key=cmp_to_key(mycmp),reverse=True)
print (''.join(ls))

按理说因为调用的是python自带的sorted()所以时间复杂度应该变低呀,变成O(nlogn)呀,为什么反而增加成了26.910626649856567秒呢?可能是因为把重新申请了存储ls那么大空间消耗时间?看到一个解释:
https://stackoverflow.com/questions/11547588/why-is-pythons-sorted-slower-than-copy-then-sort
l.sort和sorted(l)的代码是一样的,时间差别在于sorted copy的时候是用的泛型代码,可以对任何可迭代的对象copy副本用于排序,当然我们也可以假设原来的类型就是list。
list.sort can work with a known size, and swap elements within that size, sorted() has to work with unknown sizes and generic iterables, and thus may have to allocate memory as it builds (possibly forcing a memcpy if not contig.), but this should be minimal as you’ve stated. Copying a list is fairly simple as that’s just a simple malloc/memcpy op (and creation of a new PyObject*) –

但是

from functools import cmp_to_key
import  time
def mycmp(a, b):
    ab = int(a+b)
    ba = int(b+a)
    return 1 if ab > ba else -1
starttime = time.time()
num = int(sys.stdin.readline().strip())
l= sys.stdin.readline().strip().split()
l.sort(key=cmp_to_key(mycmp),reverse=True)
print (''.join(l))
endtime = time.time()
print(endtime-starttime)

用l.sort()原址排序这种方法确实快了很多啊,
对测试样例2的用时是3.3400912284851074

总结:
算法精髓:
1.代码的核心首先是定义一个ab和ba的比较

刚开始还考虑最高位相比,然后依次相比,写法比ab 和ba这种比较要麻烦
2.冒泡排序的O(n2)超时,考虑使用python自带的sorted()函数将时间复杂度降低至O(nlogn)

3.速度从快到慢,list.sort()>sorted(list)>冒泡排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值