Most frequent element in Array after replacing given index by K for Q queries

Given an array arr[] of size N, and Q queries of the form {i, k} for which, the task is to print the most frequent element in the array after replacing arr[i] by k.

Example :

Input: arr[] = {2, 2, 2, 3, 3}, Querry = {{0, 3}, {4, 2}, {0, 4}}
Output: 3 2 2
First query: Setting arr[0] = 3 modifies arr[] = {3, 2, 2, 3, 3}. So, 3 has max frequency.
Second query: Setting arr[4] = 2, modifies arr[] = {3, 2, 2, 3, 2}. So, 2 has max frequency.
Third query: Setting arr[0] = 4, modifies arr[] = {4, 2, 2, 3, 2}. So, 2 has max frequency

Input: arr[] = {1, 2, 3, 4, 3, 3} Querry = {{0, 2}, {3, 2}, {2, 4}}
Output: 3 2 2

Naive Approach:
For every query, replace arr[i] by K, and traverse over the whole array and count the frequency of every array element and print the most frequent of them.
Time Complexity: O(N * Q)
Auxiliary Space: O(N)



Efficient Approach:
The above approach can be optimized by precomputing the frequencies of every array element and maintain frequency-array element pairings in a set to obtain the most frequent element in O(1). Follow the steps below to solve the problem:

  1. Initialize a map to store frequencies of all array elements, and a set of pairs to store frequency-element pairings. In the set, store the frequencies as negative. This ensures that the first pair stored at the beginning of the set, i.e. s.begin(), is the {-(maximum frequency), most frequent element} pairing.
  2. For every query, while removing the array element at ith index, do the following tasks:
    • Find the frequency of arr[i] from the map, that is mp[arr[i]].
    • Remove the pair {-mp[arr[i]], arr[i]} from the set.
    • Update the set after decreasing the frequency of arr[i] by inserting {-(mp[arr[i] – 1), arr[i]} into the set.
    • Decrease the frequency of arr[i] in the map.
    • To insert K into the array for every query, do the following:
      • Find the frequency of K from the map, that is mp[K].
      • Remove the pair {-mp[K], K} from the set.
      • Update the set after increasing the frequency of K by inserting {-(mp[K] + 1), K} into the set.
      • Increase the frequency of K in the map.
    • Finally for each query, extract the pair at the beginning of the set. The first element in the set denotes -(maximum frequency). Hence, the second element will be the most frequent element. Print the second element of the pair.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the most
// frequent element after every
// update query on the array
  
#include <bits/stdc++.h>
using namespace std;
  
typedef long long int ll;
  
// Function to print the most
// frequent element of array
// along with update querry
void mostFrequent(ll arr[], ll n, ll m,
                  vector<vector<ll> > q)
{
    ll i;
  
    // Stores element->fequencies
    // mappings
    map<ll, ll> mp;
  
    for (i = 0; i < n; i++)
        mp[arr[i]] += 1;
  
    // Stores frequencies->element
    // mappings
    set<pair<ll, ll> > s;
  
    // Store the frequencies in
    // negative
    for (auto it : mp) {
        s.insert(make_pair(-(it.second),
                           it.first));
    }
  
    for (i = 0; i < m; i++) {
  
        // Index to be modified
        ll j = q[i][0];
  
        // Value to be inserted
        ll k = q[i][1];
  
        // Store the frequency of
        // arr[j] and k
        auto it = mp.find(arr[j]);
        auto it2 = mp.find(k);
  
        // Remove mapping of arr[j]
        // with previous frequency
        s.erase(make_pair(-(it->second),
                          it->first));
  
        // Update mapping with new
        // frequency
        s.insert(make_pair(-((it->second)
                             - 1),
                           it->first));
  
        // Update frequency of arr[j]
        // in the map
        mp[arr[j]]--;
  
        // Remove mapping of k
        // with previous frequency
        s.erase(make_pair(-(it2->second),
                          it2->first));
  
        // Update mapping of k
        // with previous frequency
        s.insert(make_pair(-((it2->second)
                             + 1),
                           it2->first));
  
        // Update frequency of k
        mp[k]++;
  
        // Replace arr[j] by k
        arr[j] = k;
  
        // Display maximum frequent element
        cout << (*s.begin()).second << " ";
    }
}
// Driver Code
int main()
{
  
    ll i, N, Q;
    N = 5;
    Q = 3;
    ll arr[] = { 2, 2, 2, 3, 3 };
    vector<vector<ll> > querry = {
        { 0, 3 },
        { 4, 2 },
        { 0, 4 }
    };
  
    mostFrequent(arr, N, Q, querry);
}

chevron_right


Output:

3 2 2

Time Complexity: O(N + (Q * LogN))
Auxiliary Space: O(N)

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.