解题笔记(一):查找热点数据 | 豆包MarsCode AI 刷题

138 阅读3分钟

题目分析

题目要求:从一个数组中找出出现频率最高的前 k 个元素,并按升序输出。需要满足以下条件:

  1. 输出为一个字符串,数字之间用逗号分隔。
  2. 算法时间复杂度必须优于 O(n log n)

难点分析

  1. 时间复杂度限制:传统排序方式是 O(n log n),本题要求比排序更高效,需使用堆或哈希表等数据结构。
  2. 频率统计:需要快速统计每个元素的出现次数。
  3. 结果输出格式化:按频率前 k 高、升序排列,返回字符串格式。

解题思路

  1. 统计频率使用 Python 的 collections.Counter 对数组进行统计,得到每个元素的频率。

  2. 使用堆优化

    • 利用小顶堆(最小堆)保持频率最高的 k 个元素。
    • 堆中存储 (频率, 元素) 的元组,优先依据频率排序。
    • 遍历时,当堆的大小超过 k,移除堆顶(频率最小的元素)。
  3. 结果处理

    • 从堆中提取元素时,由于堆不保证顺序,需要额外对元素进行升序排列。
    • 将排序后的结果转为字符串输出。

时间复杂度分析

  • 频率统计O(n),其中 n 是数组长度。
  • 堆操作:每次插入或删除堆的复杂度为 O(log k),最多遍历 n 次,总复杂度为 O(n log k)
  • 结果排序:提取堆中 k 个元素后排序,复杂度为 O(k log k)总体复杂度O(n log k)

代码详解

以下是代码与详解:

  python
  ​
  ​
  复制代码
  import heapq
  from collections import Counter
  ​
  def solution(nums, k):
      """
      查找出现频率最高的前 k 个元素,并返回按升序排列的字符串
      :param nums: List[int] 输入数组
      :param k: int 需要返回的高频元素个数
      :return: str 按升序排列的高频元素字符串
      """
      # 1. 统计每个元素的频率
      freq_map = Counter(nums)
      # freq_map 示例:{1: 3, 2: 2, 3: 1}
  ​
      # 2. 使用最小堆保存频率最高的 k 个元素
      heap = []  # 小顶堆,存储 (频率, 元素) 元组
  ​
      for num, freq in freq_map.items():
          heapq.heappush(heap, (freq, num))  # 插入堆
          # 如果堆的大小超过 k,则弹出频率最低的元素
          if len(heap) > k:
              heapq.heappop(heap)
  ​
      # 3. 提取堆中元素并排序
      top_k = [num for freq, num in heap]  # 仅保留元素部分
      top_k.sort()  # 按升序排列
  ​
      # 4. 返回结果
      return ",".join(map(str, top_k))  # 拼接成字符串

测试结果

测试用例:

  
  python
  ​
  ​
  复制代码
  if __name__ == "__main__":
      print(solution([1, 1, 1, 2, 2, 3], 2))  # 输出: "1,2"
      print(solution([1], 1))  # 输出: "1"
      print(solution([4, 4, 4, 2, 2, 2, 3, 3, 1], 2))  # 输出: "2,4"

执行结果:

  • 用例 1:元素 1 出现 3 次,2 出现 2 次,答案是 "1,2"
  • 用例 2:数组中只有一个元素,直接返回 "1"
  • 用例 3:42 出现 3 次,按升序返回 "2,4"

个人感悟

  1. 堆的灵活应用本题中的小顶堆操作是一个亮点,它既能限制空间复杂度(仅存储 k 个元素),又保证了性能。学习这种思路后,我对堆的实际应用场景有了更深的理解,特别是在处理“前 K 大”或“前 K 小”问题时,这是一种高效的通用方法。
  2. 格式化输出的细节除了解决核心问题,本题还考察了结果的处理和格式化能力(如升序排序和字符串拼接)。在实际项目中,这种“结果精加工”的能力同样重要。
  3. 算法优化意识本题明确要求时间复杂度优于 O(n log n),提醒我在解题时要特别注意复杂度分析。这种限制对培养算法优化意识非常有帮助。
  4. 通用性本题方法不仅能解决“前 K 高频元素”的问题,也能扩展到其他场景,比如找到频率最高的关键词、统计流量高的页面等。这种“抽象后应用”的能力在实际开发中非常实用。

下一步学习计划:我计划进一步学习和应用堆、