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

本文探讨了在处理大量数据排序时,如何通过选择更高效的排序算法来提升程序性能。对比了冒泡排序、Python内置sorted()函数及list.sort()方法的效率,并分析了各自的时间复杂度和实际运行时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接: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.youkuaiyun.com/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)>冒泡排序

### 使用 Python 计算四个数字组成最大给定四个数字时,可以通过排列组合的方式找到所有可能的四位组合,并从中筛选出最大值。以下是具体的实现方法: #### 方法概述 为了得到由四个数字组成最大,可以先生成这四个数字的所有全排列,再将每种排列转化为对应的整数形式并比较大小。 --- #### 实现代码 以下是一段完整的 Python 代码来完成此功能: ```python from itertools import permutations def find_max_number(digits): # 将输入的数字转为字符以便于后续操作 str_digits = [str(d) for d in digits] # 获取所有的排列方式 all_permutations = [''.join(p) for p in permutations(str_digits)] # 转化为整数并寻找其中的最大值 max_num = int(max(all_permutations)) return max_num # 测试据 digits = [1, 2, 3, 4] # 输入四个数字 result = find_max_number(digits) print(f"由 {digits} 组成最大: {result}") ``` 上述代码的核心逻辑在于使用 `itertools.permutations` 函生成所有可能的排列[^1],并将它们逐一拼接成字符后再转化成整数进行比较。 --- #### 输出结果解释 对于测试据 `[1, 2, 3, 4]`,该程序会输出如下结果: ``` 由 [1, 2, 3, 4] 组成最大: 4321 ``` 这是因为,在所有可能的排列中(如 `'1234', '1243', ..., '4321'`),`'4321'` 是字典序中的最大值。 --- #### 关键点分析 1. **排列生成** 使用标准库模块 `itertools.permutations` 来高效生成所有排列。 2. **字符处理** 数字列表需先转换为字符列表才能方便地通过 `''.join()` 进行连接[^1]。 3. **性能优化** 对于仅有四个数字的情况,这种方法效率较高,因为总共只有 \(4! = 24\) 种排列可能性。 --- 问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值