查找热点数据问题| 豆包MarsCode AI 刷题

23 阅读2分钟

问题描述

给你一个整数数组 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

思路:

  1. 统计频率

    • 使用 collections.Counter 来统计列表中每个元素的频率。Counter 会返回一个字典,其中键是列表中的元素,值是该元素出现的次数。
  2. 找出频率前 k 高的元素

    • 使用 heapq.nlargest 函数来找出频率最高的 k 个元素。heapq.nlargest 函数接受三个参数:要返回的元素数量 k,一个可迭代对象(在这里是 frequency.keys(),即所有不同的元素),以及一个用于比较元素的关键字函数(在这里是 frequency.get,即根据元素的频率来比较)。
    • heapq.nlargest 实际上是通过维护一个大小为 k 的最小堆来实现的,这使得它在处理大数据集时非常高效。
  3. 排序并转换为字符串

    • 使用 sorted 函数对找出的频率前 k 高的元素进行升序排序。
    • 使用 map(str, ...) 将排序后的元素转换为字符串。
    • 使用 ','.join(...) 将字符串列表连接成一个以逗号分隔的字符串。
  4. 返回结果

    • 返回最终的字符串结果。