【算法题解】字符串数组中第 k 大整数 — Python 实现详解
题目描述
给定一个字符串数组 nums
,其中每个字符串都表示一个没有前导零的整数。我们需要找到其中第 k
大的整数并返回它对应的字符串。
注意:
nums
中的每个字符串都表示一个整数,但可能非常大(长度最多 100),无法直接转换为整数类型进行比较。- 重复的数字视为不同的元素,即统计第
k
大时不会去重。 - 输入保证:
1 <= k <= nums.length <= 10^4
,1 <= nums[i].length <= 100
,nums[i]
只包含数字且无前导零。
题目示例
示例 1:
输入:nums = ["3","6","7","10"], k = 4
输出:"3"
解释:
nums 中的数字排序为 ["3","6","7","10"]
第 4 大整数是 "3"
示例 2:
输入:nums = ["2","21","12","1"], k = 3
输出:"2"
解释:
排序后 nums = ["1","2","12","21"]
第 3 大整数是 "2"
示例 3:
输入:nums = ["0","0"], k = 2
输出:"0"
解释:
排序后 nums = ["0","0"]
第 2 大整数是 "0"
解题分析
该题的核心难点在于:
- 字符串数字的比较:
数字用字符串形式给出,且长度最大可达 100。
直接将字符串转成整数比较会导致数据溢出或效率低下。 - 正确排序规则:
字符串数字的大小比较应基于数值大小,而不是字符串的字典序(除非长度相等)。
如何比较两个字符串表示的数字大小?
- 先比较长度:长度长的数字更大(例如,"1234" > "567")。
- 长度相同,则逐字符比较(类似字典序),从最高位往后比较。
解题方法
Python 提供了灵活的排序方法,可以通过自定义排序键(key
)实现正确的排序。
具体步骤:
- 定义排序键
使用key=lambda x: (len(x), x)
,即先按照数字字符串的长度升序排序,再按字典序升序排序。
这样排序后,数组从小到大排列。 - 取第 k 大
排序后,第 k 大的数字就是倒数第 k 个元素,索引为-k
。 - 返回结果
直接返回倒数第 k 个元素即可。
代码实现(Python)
from typing import List
class Solution:
def kthLargestNumber(self, nums: List[str], k: int) -> str:
# 按数字大小升序排序
nums.sort(key=lambda x: (len(x), x))
# 返回倒数第 k 个元素,即第 k 大数字
return nums[-k]
代码解析
nums.sort(key=lambda x: (len(x), x))
:
对字符串先按长度排序,再按字典序排序,保证整体按数字大小升序。return nums[-k]
:
列表已经升序排序,倒数第 k 个即为第 k 大数字。
时间复杂度分析
- 排序的时间复杂度为 O(N log N * M),
其中 N 是数组长度,M 是最大字符串长度(比较两个字符串最多比较 M 位)。 - 由于 M 最大为 100,且 N 最大为 10^4,算法在现实中运行效率足够。
示例说明
以示例 2 为例:
nums = ["2", "21", "12", "1"]
k = 3
- 排序后,
nums
变成["1", "2", "12", "21"]
按数字大小升序排列。 - 第 3 大数字是倒数第 3 个,即索引
-3
的元素"2"
。
思路比较与总结
方法 |
优点 |
缺点 |
转整数比较 |
简单直观 |
数据大时会溢出 |
自定义比较 |
适用所有长度数字,灵活 |
代码稍复杂,需保证比较正确 |
预处理排序 |
利用内置排序快速,代码简洁 |
依赖排序稳定和正确的 key |
本题最优方案是利用 Python 的排序稳定性和灵活的排序键,实现基于长度和字典序的排序,保证高效准确。
总结
- 本题的关键是正确比较字符串表示的大整数。
- 通过先比较长度,再字典序比较,能够实现数字大小排序。
- 利用内置排序和合适的排序键,可以轻松得到第 k 大数字。
- 此方法不仅高效,而且代码简洁,适合面试和实际编程使用。