豆包 Mars Code刷题 | 对于查找数据问题的分析

155 阅读3分钟

一、问题重述

问题描述

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

二、解题思路

  1. 统计频率:首先,我们需要统计数组中每个元素的出现频率。可以使用 collections.Counter 来快速实现这一点。
  2. 按频率排序:接下来,我们需要根据频率对元素进行排序。由于题目要求时间复杂度优于 O(n log n),我们可以使用堆(heap)来实现这一步。
  3. 选择前 k 个元素:从堆中取出前 k 个频率最高的元素。
  4. 按升序排列:最后,将这些元素按升序排列,并转换为字符串格式。

三、参考代码讲解

from collections import Counter
import heapq

def solution(nums, k):
    # 统计每个元素的频率
    frequency = Counter(nums)
    
    # 使用堆来获取前 k 个高频元素
    # 这里我们使用最小堆,因为我们只需要前 k 个元素
    heap = []
    for num, freq in frequency.items():
        # 将频率和元素的负值(因为我们需要最大堆)放入堆中
        heapq.heappush(heap, (freq, -num))
        # 如果堆的大小超过 k,弹出最小的元素
        if len(heap) > k:
            heapq.heappop(heap)
    
    # 从堆中取出前 k 个元素,并按升序排列
    result = []
    while heap:
        freq, num = heapq.heappop(heap)
        result.append(-num)
    
    # 将结果转换为字符串格式
    return ','.join(map(str, sorted(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. 使用堆:我们使用最小堆来维护前 k 个高频元素。每次插入元素时,如果堆的大小超过 k,则弹出最小的元素。
  3. 取出结果:从堆中取出前 k 个元素,并按升序排列。
  4. 转换为字符串:将结果转换为字符串格式,元素之间用逗号分隔。

四、AI刷题心得


通过近一个月的刷题,感觉豆包Mars Code进步很大,从最开始需要prompt多次才能找出正确答案,到现在对高难度题高难度题的一次prompt就可以出来正确解答,确实很不可思议。豆包每次给的解题思路也很准确,但是我认为不应太过于依赖AI,要先自己多思考,建立好自己刷题的思维,真是到实在解决不了的问题再问它。


好了本次分享就到这里了。如果对我感兴趣,可以关注我的GitHub。 也可以加我的飞书一起交流。