为了解决这个问题,我们可以使用一个哈希表来统计每个数字出现的次数,然后使用一个最小堆(或者优先队列)来找到出现频率前k高的元素。以下是解决这个问题的步骤:
- 使用哈希表(例如Python中的字典)统计数组中每个数字出现的次数。
- 使用一个最小堆来存储出现频率最高的k个元素。最小堆中的元素是一个元组,包含数字出现的次数和数字本身。
- 遍历哈希表,对于每个元素,如果堆中元素个数小于k,则直接将其加入堆中;如果堆中元素个数等于k,且当前元素的频率高于堆顶元素的频率,则弹出堆顶元素,并将当前元素加入堆中。
- 遍历结束后,堆中存储的就是出现频率前k高的元素。
- 将堆中的元素按照数字本身的大小升序排列,并转换为字符串格式,元素之间用逗号分隔。
统计频率:首先,我们遍历整个数组,使用一个哈希表(例如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)。