NLeetCode Solutions
ProblemsPatternsStatistics
© 2026 Created by Trịnh Minh Nhật
GitHubLeetCode
Related posts
  • 49. Group AnagramsMedium
  • 217. Contains DuplicateEasy
  • 1. Two SumEasy
  • 242. Valid AnagramEasy
  • 13. Roman to IntegerEasy

347. Top K Frequent Elements

Medium
ArrayHash TableDivide and ConquerSortingHeap (Priority Queue)Bucket SortCountingQuickselect
Companies:
Pocket GemsYelp
Answered: Mar 2, 2026
View on LeetCode

Problem Description

Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order.

Examples

Example 1

Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]

Example 2

Input: nums = [1], k = 1
Output: [1]

Example 3

Input: nums = [1,2,1,2,1,2,3,1,3,2], k = 2
Output: [1,2]

Constraints

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104
  • k is in the range [1, the number of unique elements in the array].
  • It is guaranteed that the answer is unique.

Follow-up

Your algorithm's time complexity must be better than $O(n \log n)$, where n is the array's size.


Solutions

Complexity Analysis

Time Complexity:O(nlogn)

We iterate through the nums array once to build the frequency map, which takes O(n)O(n)O(n) time. Sorting the frequency map takes O(mlog⁡m)O(m \log m)O(mlogm) time, where m is the number of unique elements in the array. In the worst case, m can be equal to n (when all elements are unique), leading to O(nlog⁡n)O(n \log n)O(nlogn) time complexity.

Space Complexity:O(n)

We use a hash map to store the frequency of each element, which requires O(n)O(n)O(n) space in the worst case.

In this solution, we first create a frequency map to count the occurrences of each number in the nums array. We then sort this frequency map based on the frequency values in descending order. Finally, we return the keys of the sorted map, which represent the numbers, and slice the first k elements to get the top k frequent elements.

Complexity Analysis

Time Complexity:O(nlogk)

We iterate through the nums array once to build the frequency map, which takes O(n)O(n)O(n) time. We then iterate through the frequency map, which takes O(m)O(m)O(m) time, where m is the number of unique elements. For each element, we perform a heap operation that takes O(log⁡k)O(\log k)O(logk) time. In the worst case, m can be equal to n (when all elements are unique), leading to O(nlog⁡k)O(n \log k)O(nlogk) time complexity.

Space Complexity:O(k)

We use a min-heap to store the top k frequent elements, which requires O(k)O(k)O(k) space. Additionally, we use a hash map to store the frequency of each element, which requires O(m)O(m)O(m) space, where m is the number of unique elements. In the worst case, m can be equal to n, leading to O(n)O(n)O(n) space complexity. However, since we only keep track of the top k elements, the overall space complexity is O(k)O(k)O(k).

In this solution, we use a min-heap (priority queue) to keep track of the top k frequent elements. We first build a frequency map to count the occurrences of each number. Then, we iterate through the frequency map and push each number along with its frequency into the min-heap. If the size of the heap exceeds k, we remove the smallest element (the one with the lowest frequency). Finally, we extract the numbers from the heap, which represent the top k frequent elements.

Complexity Analysis

Time Complexity:O(n)

We iterate through the nums array once to build the frequency map, which takes O(n)O(n)O(n) time. We then iterate through the frequency map to fill the buckets, which takes O(m)O(m)O(m) time, where m is the number of unique elements. Finally, we iterate through the buckets to collect the top k elements, which takes O(n)O(n)O(n) time in the worst case (when all elements are unique). Therefore, the overall time complexity is O(n)O(n)O(n).

Space Complexity:O(n)

We use a frequency map to store the count of each number, which takes O(m)O(m)O(m) space, where m is the number of unique elements. We also use a list of buckets to group numbers by their frequency, which takes O(n)O(n)O(n) space in the worst case. Therefore, the overall space complexity is O(n)O(n)O(n).

In this solution, we use a bucket sort approach to group numbers based on their frequency. We first build a frequency map to count the occurrences of each number. Then, we create a list of buckets where the index represents the frequency and the value is a list of numbers that have that frequency. Finally, we iterate through the buckets in reverse order (from highest frequency to lowest) and add numbers to the result list until we have k elements.

Conclusion

ApproachRatingTime ComplexitySpace ComplexityAdvantagesDisadvantages
Sorting
O(nlog⁡n)O(n \log n)O(nlogn)O(n)O(n)O(n)Simple to understand and implement⚠️ Does not meet the follow-up requirement of better than O(nlog⁡n)O(n \log n)O(nlogn)
Min-Heap
O(nlog⁡k)O(n \log k)O(nlogk)O(k)O(k)O(k)Efficient when k is much smaller than n, meets follow-up requirementRequires understanding of heap data structure
Bucket Sort
O(n)O(n)O(n)O(n)O(n)O(n)Linear time complexity, no sorting or heap overhead, meets follow-up requirementRequires O(n)O(n)O(n) extra space for the bucket array

The optimal approach for this problem is Solution 3: Bucket Sort, which achieves O(n)O(n)O(n) time complexity and O(n)O(n)O(n) space complexity. This approach leverages the fact that element frequencies are bounded by the array length, using bucket indices to represent frequencies and avoiding any sorting or heap operations entirely.


Previous344. Reverse String
Next509. Fibonacci Number
Related posts
  • 49. Group AnagramsMedium
  • 217. Contains DuplicateEasy
  • 1. Two SumEasy
  • 242. Valid AnagramEasy
  • 13. Roman to IntegerEasy
On this page
12 lines
1class Solution:
2 def topKFrequent(self, nums: List[int], k: int) -> List[int]:
3 my_dict = defaultdict(int)
4
5 # Create a list to store the frequency of each number: frequency[num] = count
6 for num in nums:
7 my_dict[num] += 1
8
9 # Sort the dictionary by frequency in descending order
10 sorted_dict = dict(sorted(my_dict.items(), key=lambda x: x[1], reverse=True))
11
12 return list(sorted_dict.keys())[:k]
21 lines
1import heapq
2
3class Solution:
4 def topKFrequent(self, nums: List[int], k: int) -> List[int]:
5 my_dict = defaultdict(int)
6
7 # Create a list to store the frequency of each number: frequency[num] = count
8 for num in nums:
9 my_dict[num] += 1
10
11 min_heap = []
12
13 for num, freq in my_dict.items():
14 heapq.heappush(min_heap, (freq, num))
15
16 # If the heap exceeds size k, remove the smallest element
17 if len(min_heap) > k:
18 heapq.heappop(min_heap)
19
20 # Extract the numbers from the heap
21 return [num for freq, num in min_heap]
24 lines
1class Solution:
2 def topKFrequent(self, nums: List[int], k: int) -> List[int]:
3 my_dict = defaultdict(int)
4
5 # Create a list to store the frequency of each number: frequency[num] = count
6 for num in nums:
7 my_dict[num] += 1
8
9 # Create a list of buckets where the index represents the frequency and the value is a list of numbers with that frequency
10 bucket = [[] for i in range(len(nums) + 1)]
11
12 # Fill the bucket with numbers based on their frequency
13 for num, freq in my_dict.items():
14 bucket[freq].append(num)
15
16 res = []
17
18 # Iterate through the bucket in reverse order (from highest frequency to lowest) and add numbers to the result list until we have k elements
19 for i in range(len(bucket) - 1, 0, -1):
20 for num in bucket[i]:
21 res.append(num)
22
23 if len(res) == k:
24 return res