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

52 阅读3分钟

为了解决这个问题,我们可以使用一个哈希表来统计每个数字出现的次数,然后使用一个最小堆(或者优先队列)来找到出现频率前k高的元素。以下是解决这个问题的步骤:

  1. 使用哈希表(例如Python中的字典)统计数组中每个数字出现的次数。
  2. 使用一个最小堆来存储出现频率最高的k个元素。最小堆中的元素是一个元组,包含数字出现的次数和数字本身。
  3. 遍历哈希表,对于每个元素,如果堆中元素个数小于k,则直接将其加入堆中;如果堆中元素个数等于k,且当前元素的频率高于堆顶元素的频率,则弹出堆顶元素,并将当前元素加入堆中。
  4. 遍历结束后,堆中存储的就是出现频率前k高的元素。
  5. 将堆中的元素按照数字本身的大小升序排列,并转换为字符串格式,元素之间用逗号分隔。

统计频率:首先,我们遍历整个数组,使用一个哈希表(例如Python中的字典)来记录每个数字出现的次数。这一步的时间复杂度是O(n),因为我们需要查看数组中的每个元素一次。 构建最小堆:接着,我们从哈希表中提取每个数字及其对应的频率,并构建一个最小堆。在最小堆中,我们存储的是元组,其中包含数字的频率和数字本身。由于我们只需要前k个最频繁的元素,当堆的大小超过k时,我们会弹出堆顶元素(即当前频率最低的元素)。这一步的时间复杂度是O(n),因为每个元素最多被插入和弹出堆一次。 提取结果:构建完最小堆后,我们得到了出现频率最高的k个元素。然后,我们需要将这些元素按照它们本身的值排序,以满足题目中按升序排列的要求。这一步的时间复杂度是O(k log k),因为我们需要对k个元素进行排序。 输出结果:最后,我们将排序后的k个元素转换为字符串,并用逗号分隔。这一步的时间复杂度是O(k),因为我们需要遍历k个元素一次。

以下是这个问题的Python代码实现:

python
import heapq

def topKFrequent(nums, k):
    count_map = {}
    # Step 1: Count the frequency of each number
    for num in nums:
        count_map[num] = count_map.get(num, 0) + 1

    # Step 2: Use a min heap to find the top k frequent elements
    min_heap = []
    for num, count in count_map.items():
        heapq.heappush(min_heap, (count, num))
        if len(min_heap) > k:
            heapq.heappop(min_heap)

    # Step 4: Convert the heap to a sorted string
    result = []
    while min_heap:
        result.append(str(min_heap[0][1]))
        heapq.heappop(min_heap)
    
    # Sort the result in ascending order
    result.sort()
    return ','.join(result[:k])

# Test cases
print(topKFrequent([1, 1, 1, 2, 2, 3], 2))  # Output: "1,2"
print(topKFrequent([1], 1))  # Output: "1"
print(topKFrequent([4, 4, 4, 2, 2, 2, 3, 3, 1], 2))  # Output: "2,4"

这个算法的时间复杂度是O(n + n/k + k log k),其中n是数组大小。由于k远小于n,所以这个复杂度优于O(n log n)。在最坏的情况下,我们需要将所有元素加入堆中,然后弹出k个元素,所以时间复杂度是O(n log k),这仍然优于O(n log n)。