问题描述
给你一个整数数组 nums 和一个整数 k,请你用一个字符串返回其中出现频率前 k 高的元素。请按升序排列。
你所设计算法的时间复杂度必须优于 O(n log n),其中 n 是数组大小。
输入
- nums: 一个正整数数组
- k: 一个整数
返回
返回一个包含 k 个元素的字符串,数字元素之间用逗号分隔。数字元素按升序排列,表示出现频率最高的 k 个元素。
参数限制
- 1 <= nums[i] <= 10^4
- 1 <= nums.length <= 10^5
- k 的取值范围是 [1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
测试样例
样例1:
输入:
nums = [1, 1, 1, 2, 2, 3], k = 2
输出:"1,2"
解释:元素 1 出现了 3 次,元素 2 出现了 2 次,元素 3 出现了 1 次。因此前两个高频元素是 1 和 2。
样例2:
输入:
nums = [1], k = 1
输出:"1"
样例3:
输入:
nums = [4, 4, 4, 2, 2, 2, 3, 3, 1], k = 2
输出:"2,4"
解答:
import heapq from collections import Counter
def solution(nums, k): # 统计每个元素的频率 frequency = Counter(nums)
# 使用最小堆来找出频率前 k 高的元素
# heapq.nlargest 返回前 k 个频率最大的元素
top_k_elements = heapq.nlargest(k, frequency.keys(), key=frequency.get)
# 返回升序排列的结果,并转换为字符串
return ','.join(map(str, sorted(top_k_elements)))
if name == "main": # 测试用例 print(solution([1, 1, 1, 2, 2, 3], 2) == "1,2") # 输出: True print(solution([1], 1) == "1") # 输出: True print(solution([4, 4, 4, 2, 2, 2, 3, 3, 1], 2) == "2,4") # 输出: True
思路:
-
统计频率:
- 使用
collections.Counter来统计列表中每个元素的频率。Counter会返回一个字典,其中键是列表中的元素,值是该元素出现的次数。
- 使用
-
找出频率前
k高的元素:- 使用
heapq.nlargest函数来找出频率最高的k个元素。heapq.nlargest函数接受三个参数:要返回的元素数量k,一个可迭代对象(在这里是frequency.keys(),即所有不同的元素),以及一个用于比较元素的关键字函数(在这里是frequency.get,即根据元素的频率来比较)。 heapq.nlargest实际上是通过维护一个大小为k的最小堆来实现的,这使得它在处理大数据集时非常高效。
- 使用
-
排序并转换为字符串:
- 使用
sorted函数对找出的频率前k高的元素进行升序排序。 - 使用
map(str, ...)将排序后的元素转换为字符串。 - 使用
','.join(...)将字符串列表连接成一个以逗号分隔的字符串。
- 使用
-
返回结果:
- 返回最终的字符串结果。