Problem Statement
Given an array of n integers, find the most frequent element in it i.e., the element that occurs the maximum number of times. If there are multiple elements that appear a maximum number of times, find the smallest of them.
Examples
Example 1:
Input: array = [1, 2, 2, 2, 3, 3]
Output: 2
Explanation: Since the number 2 appears the most (3 times). It is the frequent element.
Example 2:
Input: array = [1, 1, 2, 2, 3]
Output: 1
Explanation: Both 1 and 2 appears twice, however 1 is smaller. So, 1 is the most frequent element.
Example 3:
Input: array = [5, 4, 3, 2, 1]
Output: 1
Explanation: All the elements appear once, however 1 is the smallest among them.
Approaches
1️⃣ Brute Force Approach
Intuition:
A brute-force way to solve this problem will be to use two loops:
- First loop to iterate on the array, selecting an element.
- Second loop to traverse the remaining array to find the occurrences of the selected element in the first loop.
Maintain a visited array to mark the elements to keep track of duplicate elements that were already taken into account.
Approach:
- Initialize a visited array of boolean type having size n, where n is the size of the array with all elements set to false. Also, declare the following variables :
- maxFreq - to store the frequency of the highest occurring element.
- maxEle - to store the highest occurring element in the array.
- In the first loop, start iterating on the elements of the array selecting one element at a time.
- In the second loop, iterate on the rest portion of the array and count the frequency (number of occurrences) of the selected element. And every time, the same element is found, mark the corresponding index in the visited array as true.
- If the frequency of the current element is found greater than maxFreq, update maxFreq and maxEle with the new frequency and new element respectively.
- If the frequency of the current element is the same as maxFreq, store the smaller of maxEle and the current element in maxEle.
- Before starting the second loop, check if the element is marked as unvisited. Skip the element if it is visited because its frequency has already been taken into consideration.
Code:
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
/* Function to get the highest
occurring element in array nums */
int mostFrequentElement(vector<int> &nums) {
// Variable to store the size of array
int n = nums.size();
// Variable to store maximum frequency
int maxFreq = 0;
/* Variable to store element
with maximum frequency */
int maxEle;
// Visited array
vector<bool> visited(n, false);
// First loop
for(int i = 0; i < n; i++) {
// Skip second loop if already visited
if(visited[i]) continue;
/* Variable to store frequency
of current element */
int freq = 0;
// Second loop
for(int j = i; j < n; j++) {
if(nums[i] == nums[j]) {
freq++;
visited[j] = true;
}
}
/* Update variables if new element having
highest frequency is found */
if(freq > maxFreq) {
maxFreq = freq;
maxEle = nums[i];
} else if(freq == maxFreq) {
maxEle = min(maxEle, nums[i]);
}
}
// Return the result
return maxEle;
}
};
int main() {
vector<int> nums = {4, 4, 5, 5, 6};
/* Creating an instance of
Solution class */
Solution sol;
/* Function call to get the
highest occurring element in array nums */
int ans = sol.mostFrequentElement(nums);
cout << "The highest occurring element in the array is: " << ans;
return 0;
}
Complexity Analysis:
- Time Complexity:
O(n*n)
(wheren
is the size of the array given) – Using two nested loops. - Space Complexity:
O(n)
– Using a visited array of sizen
and a couple of variables.
2️⃣ Hashing (Optimal Approach)
Intuition:
An optimal approach to solve this question will be to use a Hashmap
, a data structure that stores key-value pairs.
- Key will denote the element in the array.
- Value will store the frequency of the element in the array.
In C++ it is the unordered_map
.
Or we can use hashing with an array, also known as using a “direct address table”
Approach:
- Either take an HashMap (unordered_map) or array.
- Traverse the array and update the frequencies of each element in the hash table.
- Iterate through the hash table to find the element with the highest frequency.
- This approach has a time complexity of
O(n)
, wheren
is the number of elements in the array, and a space complexity ofO(k)
, wherek
is the number of distinct elements.
Code:
Using unordered_map
:
#include <iostream>
#include <vector>
#include <unordered_map>
int highestOccurringElement(const std::vector<int>& arr) {
// Step 1: Create a frequency map to count occurrences of each element
std::unordered_map<int, int> frequencyMap;
// Step 2: Populate the frequency map
for (int num : arr) {
frequencyMap[num]++;
}
// Step 3: Find the element with the highest frequency
int maxFrequency = 0;
int mostFrequentElement = arr[0];
for (const auto& pair : frequencyMap) {
if (pair.second > maxFrequency) {
maxFrequency = pair.second;
mostFrequentElement = pair.first;
}
}
return mostFrequentElement;
}
int main() {
std::vector<int> arr = {1, 3, 2, 1, 4, 1, 2, 2};
int result = highestOccurringElement(arr);
std::cout << "The highest occurring element is: " << result << std::endl;
return 0;
}
Time and Space Complexity
- Time Complexity:
O(n)
because we make a single pass to count the frequencies and another pass to find the maximum frequency. - Space Complexity:
O(k)
, wherek
is the number of distinct elements in the array (for storing the frequencies in the hash map).
Using Simple Array Hashing:
#include <iostream>
#include <string>
using namespace std;
#define SIZE 6 // size of the array
bool visited[SIZE] = {false};
int frequency[SIZE] = {0};
int highestOccurringElement(int arr[], int size) {
int maxElm = 0;
int maxFreq = 0;
// Count frequencies of each element in the input array.
for(int i = 0; i < size; i++){
if (visited[i] == true){
continue;
}
frequency[arr[i]]++;
}
// Find the most frequent element
for (int i = 0; i < size; i++) {
if (frequency[i] > maxFreq) {
maxFreq = frequency[i];
maxElm = i;
}
}
return maxElm;
}
int main()
{
int arr[SIZE] = {1, 2, 3, 2, 3, 5};
int highestOccurring = highestOccurringElement(arr, SIZE);
cout << highestOccurring<<endl;
}
Time and Space Complexity
- Time Complexity:
O(n + k)
, wheren
is the number of elements in the input array and k is the range of possible values (maxValue + 1
).- The
O(n)
term is for iterating through the input array. - The
O(k)
term is for iterating through the frequency array to find the most frequent element.
- The
- Space Complexity:
O(k)
, wherek
ismaxValue + 1
, due to the size of the frequency array.
Using Vector (dynamic array):
#include <iostream>
#include <vector>
void countFrequenciesUsingArrayHashing(const std::vector<int>& arr, int maxValue) {
// Step 1: Create the frequency array of size maxValue + 1 and initialize to 0
std::vector<int> freq(maxValue + 1, 0); // Using a vector to handle dynamic sizes
// Step 2: Count frequencies of each element in the input array
for (int num : arr) {
freq[num]++;
}
// Step 3: Output frequencies of all elements
for (int i = 0; i <= maxValue; ++i) {
if (freq[i] > 0) {
std::cout << i << ": " << freq[i] << std::endl;
}
}
}
int main() {
std::vector<int> arr = {3, 5, 3, 2, 8, 5, 5, 2};
int maxValue = 8; // Assuming we know the maximum value in the array
countFrequenciesUsingArrayHashing(arr, maxValue);
return 0;
}
Time and Space Complexity
- Time Complexity:
O(n + k)
, wheren
is the number of elements in the input array andk
is the range of values (maxValue + 1
). TheO(n)
term comes from iterating over the input array, andO(k)
comes from iterating over the frequency array. - Space Complexity:
O(k)
, wherek
ismaxValue + 1
, due to the size of the frequency array.