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:



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

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the most 
// frequent element after every 
// update query on the array 
import java.util.*;
import java.io.*;
  
class GFG{
      
// Pair class represents
// a pair of elements
static class Pair
{
    int first, second;
    Pair(int f,int s)
    {
        first = f;
        second = s;
    }
}
  
// Function to print the most 
// frequent element of array 
// along with update querry 
static void mostFrequent(int arr[], int n, int m, 
                         ArrayList<Pair> q) 
    int i; 
  
    // Stores element->fequencies 
    // mappings 
    HashMap<Integer, Integer> map = new HashMap<>();
    HashMap<Integer, Pair> map1 = new HashMap<>();
      
    for(i = 0; i < n; i++) 
    {
        if(!map.containsKey(arr[i]))
            map.put(arr[i], 1);
        else
            map.put(arr[i], map.get(arr[i]) + 1);
    
  
    // Stores frequencies->element 
    // mappings 
    TreeSet<Pair> set = new TreeSet<>(
                        new Comparator<Pair>()
    {
        public int compare(Pair p1, Pair p2)
        {
            return p2.first - p1.first;
        }
    });
  
    // Store the frequencies in 
    // bigger to smaller
    for(Map.Entry<Integer, 
                  Integer> entry : map.entrySet())
    
        Pair p = new Pair(entry.getValue(), 
                          entry.getKey());
        set.add(p);
        map1.put(entry.getKey(), p);
    
  
    for(i = 0; i < m; i++)
    
          
        // Index to be modified 
        int j = q.get(i).first;
  
        // Value to be inserted 
        int k = q.get(i).second; 
          
        // Insert the new Pair
        // with value k if it was
        // not inserted
        if(map1.get(k) == null)
        {
            Pair p = new Pair(0, k);
            map1.put(k, p);
            set.add(p);
        }
          
        // Get the Pairs of 
        // arr[j] and k 
        Pair p1 = map1.get(arr[j]); 
        set.remove(p1);
        Pair p2 = map1.get(k);
        set.remove(p2);
          
        // Decrease the frequency of 
        // mapping with value arr[j]
        p1.first--;
        set.add(p1);
  
        // Update frequency of arr[j] 
        // in the map 
        map.put(arr[j], map.get(arr[j]) - 1); 
  
        // Increase the frequency of 
        // mapping with value k
        p2.first++;
        set.add(p2);
          
        // Update frequency of k 
        if(map.containsKey(k))
            map.put(k, map.get(k) + 1); 
        else
            map.put(k, 1);
  
        // Replace arr[j] by k 
        arr[j] = k; 
  
        // Display maximum frequent element 
        System.out.print(
            set.iterator().next().second + " "); 
    
  
// Driver Code 
public static void main(String []args)
    int i, N, Q; 
    N = 5
    Q = 3
    int arr[] = { 2, 2, 2, 3, 3 }; 
      
    ArrayList<Pair> query = new ArrayList<>();
    query.add(new Pair(0, 3));
    query.add(new Pair(4, 2));
    query.add(new Pair(0, 4));
      
    mostFrequent(arr, N, Q, query); 
}
  
// This code is contributed by Ganeshchowdharysadanala
chevron_right


Output:
3 2 2 

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





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.



Improved By : Ganeshchowdharysadanala

Article Tags :
Practice Tags :