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

63 阅读3分钟

今天我们将在豆包MarsCode AI刷题平台上,完成《查找热点数据问题》这个算法问题,通过练习提升用户解决此类问题的能力。

《查找热点数据问题》题目如下:

image.png

问题理解

我们需要找到数组 nums 中出现频率最高的 k 个元素,并将它们按升序排列后以字符串形式返回。时间复杂度需要优于 O(n log n)

数据结构选择

  1. 频率统计:我们可以使用字典(dict)来统计每个元素的出现频率。
  2. 频率排序:为了高效地找到前 k 个高频元素,我们可以使用最小堆(heapq)来维护当前的前 k 个高频元素。

算法步骤

  1. 统计频率:遍历数组 nums,使用字典统计每个元素的出现次数。
  2. 构建最小堆:遍历字典,将元素和频率对插入最小堆中。如果堆的大小超过 k,则弹出堆顶元素(即频率最小的元素)。
  3. 提取结果:从堆中提取所有元素,按升序排列后转换为字符串返回。
import heapq
from collections import Counter

def solution(nums, k):
    # 统计每个元素的频率
    freq_dict = Counter(nums)
    
    # 使用最小堆来维护前 k 个高频元素
    min_heap = []
    for num, freq in freq_dict.items():
        # 将 (频率, 元素) 对插入最小堆
        heapq.heappush(min_heap, (freq, num))
        # 如果堆的大小超过 k,弹出堆顶元素
        if len(min_heap) > k:
            heapq.heappop(min_heap)
    
    # 从堆中提取所有元素,按升序排列
    result = [num for _, num in sorted(min_heap)]
    
    # 将结果转换为字符串返回
    return ','.join(map(str, 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")

关键步骤解释

  1. 统计频率:使用 Counter 可以快速统计每个元素的出现次数。
  2. 最小堆heapq 模块提供了最小堆的实现,我们可以利用它来维护前 k 个高频元素。
  3. 结果提取:从堆中提取元素后,按升序排列并转换为字符串。

如何使用哈希表来统计每个元素的频率?

使用哈希表(字典)来统计每个元素的频率是一个非常常见的操作。在 Python 中,我们可以使用 collections.Counter 来简化这个过程,但为了更清晰地展示,我们可以手动实现这个过程。

from collections import defaultdict

def solution(nums, k):
    # 使用 defaultdict 来统计每个元素的频率
    freq_dict = defaultdict(int)
    
    # 遍历 nums 数组,统计每个元素的频率
    for num in nums:
        freq_dict[num] += 1
    
    # 这里可以继续实现后续的逻辑,例如使用最小堆来找到前 k 个高频元素
    # 暂时返回一个占位符
    return ','.join(map(str, sorted(freq_dict.keys())))

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")

关键步骤解释

  1. 创建字典:我们使用 defaultdict(int) 来创建一个字典,其中每个键的默认值为 0
  2. 遍历数组:我们遍历 nums 数组,对于每个元素 num,我们将其对应的值加 1
  3. 统计结果:最终,freq_dict 将包含每个元素及其出现的频率。

后续步骤

在统计完频率后,你可以继续使用最小堆来找到前 k 个高频元素,并按升序排列后返回。