E卷-最大值-(100分)

最大值

问题描述

给定一组非负整数,需要重新排列这些整数的顺序,将它们拼接成一个最大的整数。由于结果可能非常大,要求返回一个字符串而不是整数。

输入格式

输入包含一行,为空格分隔的若干个非负整数。

输出格式

输出一行,为重排后得到的最大整数,以字符串形式表示。

样例输入1

10 9

样例输出1

910

样例输入2

  3 30 34 5 9

样例输出2

9534330

样例解释

样例 解释说明
样例1 将 10 和 9 重新排列,得到的最大数是 910。
样例2 将给定的数字重新排列,得到的最大数是 9534330。

数据范围

  • ,其中 是输入的整数个数。
  • 输入的每个整数

题解

自定义排序

这道题目的关键在于如何正确地比较两个数字的拼接顺序。乍一看,我们可能会认为直接按照数字大小排序就可以了,但实际上这样做是不对的。

考虑一下 3 和 30 这两个数字。如果按照数字大小排序,我们会得到 330,但实际上 303 才是更大的数。这说明我们需要一个特殊的比较规则。

解决这个问题的关键是理解:对于两个数 a 和 b,如果 ab > ba,那么 a 应该排在 b 前面。这里的 ab 和 ba 指的是将 a 和 b 拼接成的数字。

具体来说,我们可以这样实现:

  1. 将所有数字转换为字符串。
  2. 定义一个比较函数,比较 a+b 和 b+a 的大小(这里的 + 表示字符串拼接)。
  3. 使用这个比较函数对所有字符串进行排序。
  4. 将排序后的字符串拼接起来,得到最终结果。

这个方法的时间复杂度是 O(nlogn),主要来自排序的时间。对于给定的数据范围(n <= 100),这个复杂度是完全可以接受的。

需要注意的一个特殊情况是:如果输入全是 0,那么输出应该是 "0" 而不是 "00...0"。我们可以在最后检查一下,如果结果的第一个字符是 '0',就直接返回 "0"。

参考代码

  • Python
from functools import cmp_to_key

def largestNumber(nums):
    # 将数字转换为字符串
    nums = list(map(str, nums))
    
    # 定义比较函数
    def compare(a, b):
        if a + b > b + a:
            return -1
        elif a + b < b + a:
            return 1
        else:
            return 0
    
    # 使用自定义的比较函数进行排序
    nums.sort(key=cmp_to_key(compare))
    
    # 拼接结果
    result = ''.join(nums)
    
    # 处理特殊情况:如果结果全是0,应该返回"0"而不是"00...0"
    return "0" if result[0] == "0" else result

# 读取输入
nums = list(map(int, input().split()))

# 计算并输出结果
print(largestNumber(nums))
  • C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 比较函数,用于排序
int compare(const void* a, const void* b) {
    char ab[21], ba[21];
    sprintf(ab, "%d%d", *(int*)a, *(int*)b);
    sprintf(ba, "%d%d", *(int*)b, *(int*)a);
    return strcmp(ba, ab);  // 注意这里是ba和ab比较,为了降序排列
}

char* largestNumber(int* nums, int numsSize) {
    // 使用qsort进行排序
    qsort(nums, numsSize, sizeof(int), compare);
    
    // 计算结果字符串的最大可能长度
    int maxLen = numsSize * 10;
    char* result = (char*)malloc(maxLen + 1);
    result[0] = '\0';
    
    // 拼接结果
    for (int i = 0; i < numsSize; i++) {
        char temp[11];
        sprintf(temp, "%d", nums[i]);
        strcat(result, temp);
    }
    
    // 处理特殊情况:如果结果全是0,应该

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

算法刷题笔记 文章被收录于专栏

本专栏收集并整理了一些刷题笔记

全部评论

相关推荐

03-27 16:40
已编辑
门头沟学院 C++
26学院本太难了,很多公司机筛就给我刷了。机会都难拿到如果是简历存在问题也欢迎拷打————————————————————分割线——————————————————————2026.3.4更新:发完贴之后,时不时投递又收到了不少的笔试/面试邀请。主要是之前投递简历出去之后基本上都是沉默状态,年后好转了不少timeline:2026.01.21&nbsp;文远知行笔试,半年多没刷算法题&nbsp;-&gt;挂&nbsp;(后续HR说春招可以重新安排笔试)2026.2.4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;小鹏汇天&nbsp;技术一面,第二周收到结果&nbsp;-&gt;挂2026.2.12&nbsp;&nbsp;&nbsp;大众Cariad代招&nbsp;技术二面&nbsp;-&gt;Offer2026.2.28&nbsp;&nbsp;&nbsp;多益网络技术面试,由于风评太差,一直在犹豫要不要接面试&nbsp;-&gt;推迟-----------分割线-----------2026.3&nbsp;月前的某一天,临时去电网报名了二批计算机岗位的笔试2026.3.6&nbsp;从上家公司实习离职,氛围最好的一家公司,leader&nbsp;说可以帮忙转正,但是流程太长,而且我们部门据说只有一个&nbsp;hc,更想要研究生,我很有可能是会被签外包公司在这里干活,就离职了。2026.3.9&nbsp;入职新公司,大众Cariad&nbsp;以外部公司的身份进组,项目组签了三年,后续三年应该都可以在这里呆,不知道有没有希望原地跳槽。2026.3.10&nbsp;电网考试居然说我通过资格审查了,短信约我去参加资格审查,请假一天,买了&nbsp;12&nbsp;号晚上的机票回成都2026.3.15&nbsp;参加国家电网计算机类笔试2026.3.17&nbsp;电网出成绩了,感觉很低。觉得已经🈚️了2026.3.18&nbsp;收到电网面试通知,通知&nbsp;3.22-3.25&nbsp;这个时间去面试,我的岗位只招&nbsp;1&nbsp;个人。据说面试只有&nbsp;2-3&nbsp;人,不知道能不能成功----------分割线-----------2026.3.21&nbsp;电网面试结束,感觉回答的还勉勉强强,大概是2个岗位分别招1个人,一共11人面试,实际来了9人2026.3.27&nbsp;出面试成绩,满分100分,早上10:20左右发现面试成绩46,我震惊了,没截图,后面过了十分钟重新看发现面试成绩给我改成58了。但同样震惊。朋友问我是不是把面试官打了,哈哈
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

更多
正在热议
更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务