LeetCode 179中等排序
最大数 图解题解
这道题到底在问什么
给定一组非负整数 nums ,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。 注意: 输出结果可能非常大,所以你需要返回一个字符串而不是整数。
- nums
- [3,30,34,5,9]
- 输出
- "9534330"
先想最直接的笨办法
数组/字符串状态条跟着代码走:推进语句是:进入下一轮。处理过的部分不再重新枚举。(动画第 10 步)
最优解:一步一步想明白
- 3下面 9 步动画会按主解代码推进,而不是泛泛讲题型。
- 4先读清 最大数 的输入输出数组/字符串状态条跟着代码走:先把示例输入映射到代码参数:def largestNumber(self, nums):。
- 5arr = list(map(str, nums))数组/字符串状态条跟着代码走:开局只立住必要变量:arr = list(map(str, nums))。
- 6开始扫描/递归/弹栈数组/字符串状态条跟着代码走:主流程从这里开始:每轮处理一个状态。
- 7if a + b > b + a:数组/字符串状态条跟着代码走:题目条件落到这一行:if a + b > b + a:。
- 8return '0' if ans[0] == '0' else ans数组/字符串状态条跟着代码走:对应代码:return '0' if ans[0] == '0' else ans。这一行决定当前轮对答案有什么贡献。
- 9按拼接结果排序数组/字符串状态条跟着代码走:边界跟着代码看:ans = ''.join(arr)。
- 10推进到下一轮数组/字符串状态条跟着代码走:推进语句是:进入下一轮。处理过的部分不再重新枚举。
- 11return '0' if ans[0] == '0' else ans数组/字符串状态条跟着代码走:到这里,ans 已经能表达题目要求。
- 12return:return '0' if ans[0] == '0' else ans数组/字符串状态条跟着代码走:最后检查返回形态:返回值、原地修改或设计类状态,要和 LeetCode 判题方式一致。
- 15记住这题的代码骨架:题意约束先落到状态变量,再用循环或递归维护它。
⚠️ 容易写错的地方
✗ 错:按数字大小排序
✓ 对:按拼接结果排序
30 和 3 的顺序由 330 与 303 决定
✗ 错:全 0 返回 000
✓ 对:结果首位是 0 时返回 "0"
最大数不能有多余前导 0
完整代码(Python)
Python
from functools import cmp_to_key
class Solution:
def largestNumber(self, nums):
arr = list(map(str, nums))
def cmp(a, b):
if a + b > b + a:
return -1
if a + b < b + a:
return 1
return 0
arr.sort(key=cmp_to_key(cmp))
ans = ''.join(arr)
return '0' if ans[0] == '0' else ans复杂度
时间复杂度
O(n log n * L)
排序比较拼接字符串
空间复杂度
O(nL)
字符串数组
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 最大数 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
这道题为什么用「排序」,换最直接的暴力解会差在哪?+
排序抓住了本题的结构特征,把暴力解里重复的工作省掉;暴力解通常要多嵌套一层枚举,数据一大就超时。具体对比见上文「暴力解及其卡点」与「最优解逐步推演」两节。
时间复杂度为什么是 undefined?怎么推出来的?+
按上文复杂度小节的推导,时间复杂度为 undefined。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。