问题描述
给你一个整数数组 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"
解题思路
统计频率:首先,我们需要统计数组中每个元素的出现频率。可以使用 collections.Counter 来快速实现这一点。 排序:然后,我们需要根据频率对元素进行排序。由于题目要求时间复杂度优于 O(n log n),我们可以使用堆(heap)来实现这一步。 选择前 k 个:最后,我们从堆中取出前 k 个元素。
代码实现(以Python形式)
from collections import Counter
import heapq
def solution(nums, k):
# 统计每个元素的频率
frequency = Counter(nums)
# 使用最小堆来找到频率前 k 高的元素
min_heap = []
for num, freq in frequency.items():
# 将频率和元素的负值(因为我们需要最大堆)放入堆中
heapq.heappush(min_heap, (freq, -num))
# 如果堆的大小超过 k,弹出最小的元素
if len(min_heap) > k:
heapq.heappop(min_heap)
# 从堆中取出前 k 个元素,并按升序排列
result = [-num for _, num in min_heap]
result.sort()
return result
if __name__ == "__main__":
# You can add more test cases here
print(solution([1,1,1,2,2,3], 2) == [1,2])
print(solution([1], 1) == [1])
关键步骤解释
统计频率: frequency = Counter(nums) 这行代码使用 Counter 来统计每个元素的出现频率。 使用最小堆:
min_heap = []
for num, freq in frequency.items():
heapq.heappush(min_heap, (freq, -num))
if len(min_heap) > k:
heapq.heappop(min_heap)
这里我们使用最小堆来维护频率前 k 高的元素。由于 heapq 默认是最小堆,我们需要将元素的频率和元素的负值放入堆中,以便在弹出时得到频率最高的元素。
取出前 k 个元素并排序 result = [-num for _, num in min_heap] result.sort()
最后,我们从堆中取出前 k 个元素,并按升序排列。
可能面对的问题 : 如何使用哈希表来统计元素的频率?
使用哈希表(在 Python 中通常使用 collections.Counter)来统计元素的频率是一个非常高效的方法。Counter 是 collections 模块中的一个类,它可以帮助我们快速统计列表中每个元素的出现次数。
代码示例
from collections import Counter
def solution(nums, k):
# 使用 Counter 统计每个元素的频率
frequency = Counter(nums)
# 打印频率统计结果
print(frequency)
# 继续你的代码逻辑...
if __name__ == "__main__":
nums = [1, 1, 1, 2, 2, 3]
k = 2
solution(nums, k)
解释
导入 Counter: from collections import Counter
首先,我们需要从 collections 模块中导入 Counter 类。
统计频率: frequency = Counter(nums)
这行代码会创建一个 Counter 对象 frequency,它包含了 nums 列表中每个元素的出现次数。例如,对于 nums = [1, 1, 1, 2, 2, 3],frequency 将会是 Counter({1: 3, 2: 2, 3: 1})。
打印频率统计结果: print(frequency)
示例输出:
对于 nums = [1, 1, 1, 2, 2, 3],输出将会是:
Counter({1: 3, 2: 2, 3: 1})
总结
在统计完频率之后,你可以继续使用这些频率信息来实现你的算法逻辑,例如使用堆来找到频率前 k 高的元素。