力扣算法题解:自定义排序实现最大数组合
1. 题目解析与解题思路
这道力扣周赛题目要求我们设计一个算法,能够将给定的非负整数数组重新排列,使其组合成的数字是所有可能组合中最大的那个。比如给定数组[10,2],最大组合数是"210";给定[3,30,34,5,9],最大组合数是"9534330"。
这类问题在算法面试中非常典型,主要考察以下几个核心能力:
- 对数字和字符串处理的基本功
- 自定义排序规则的实现能力
- 边界条件的处理意识
2. 关键算法设计
2.1 自定义比较函数
这道题的核心在于如何定义两个数字的比较规则。传统的数值比较在这里不适用,我们需要比较的是两个数字拼接后的结果。
比如比较3和30:
- 330 vs 303 → 显然330更大
- 所以在这个规则下,3应该排在30前面
实现这个比较逻辑的Python代码如下:
def compare(a, b): return int(str(b) + str(a)) - int(str(a) + str(b))2.2 排序算法选择
虽然可以使用任意排序算法,但考虑到时间复杂度,建议使用内置的排序函数:
- Python的sorted()函数时间复杂度是O(nlogn)
- 需要指定key参数或使用functools.cmp_to_key转换比较函数
3. 完整实现与优化
3.1 基础实现版本
from functools import cmp_to_key def largestNumber(nums): nums = [str(num) for num in nums] nums.sort(key=cmp_to_key(lambda a, b: int(b+a)-int(a+b))) return str(int(''.join(nums)))3.2 边界情况处理
特别注意几个边界条件:
- 全零数组应该返回"0"而不是"000..."
- 单个零元素要正确处理
- 大数拼接时的整数溢出问题(Python不需要担心)
4. 复杂度分析与优化
4.1 时间复杂度
- 字符串转换:O(n)
- 排序:O(nlogn)
- 拼接:O(n)
- 总体:O(nlogn)
4.2 空间复杂度
- 字符串存储:O(n)
- 排序额外空间:O(n)
- 总体:O(n)
5. 常见错误与调试技巧
5.1 典型错误案例
- 直接按数字大小排序
- 忘记处理全零情况
- 比较函数实现错误导致排序不正确
5.2 调试建议
- 先用小规模测试用例验证
- 打印中间排序结果
- 特别注意0的处理
6. 类似题目扩展
掌握这个解题思路后,可以解决以下类似问题:
- 拼接最小数
- 特殊规则的字符串排序
- 自定义对象的排序问题
这道题很好地展示了如何通过自定义排序规则解决看似复杂的问题。在实际编码时,要特别注意边界条件的处理,这是区分优秀程序员的关键。